From 05f2ab18d7de0c88bf71ede58c9581a14015c51c Mon Sep 17 00:00:00 2001 From: jfk9w Date: Thu, 3 Aug 2023 11:14:42 +0300 Subject: [PATCH] refactor interface --- authorizer.go | 19 +++++++++++++++++++ client.go | 48 ++++++++++++------------------------------------ example/main.go | 38 +++++++++++++++++--------------------- 3 files changed, 48 insertions(+), 57 deletions(-) create mode 100644 authorizer.go diff --git a/authorizer.go b/authorizer.go new file mode 100644 index 0000000..532e474 --- /dev/null +++ b/authorizer.go @@ -0,0 +1,19 @@ +package lkdr + +import "context" + +type Authorizer interface { + GetCaptchaToken(ctx context.Context, userAgent, siteKey, pageURL string) (string, error) + GetConfirmationCode(ctx context.Context, phone string) (string, error) +} + +type authorizerKey struct{} + +func WithAuthorizer(ctx context.Context, authorizer Authorizer) context.Context { + return context.WithValue(ctx, authorizerKey{}, authorizer) +} + +func getAuthorizer(ctx context.Context) Authorizer { + authorizer, _ := ctx.Value(authorizerKey{}).(Authorizer) + return authorizer +} diff --git a/client.go b/client.go index 89da238..eec747d 100644 --- a/client.go +++ b/client.go @@ -11,7 +11,6 @@ import ( "github.com/go-playground/validator" "github.com/jfk9w-go/based" "github.com/pkg/errors" - "go.uber.org/multierr" ) const ( @@ -26,14 +25,6 @@ type TokenStorage interface { UpdateTokens(ctx context.Context, phone string, tokens *Tokens) error } -type ConfirmationProvider interface { - GetConfirmationCode(ctx context.Context, phone string) (string, error) -} - -type CaptchaTokenProvider interface { - GetCaptchaToken(ctx context.Context, userAgent, siteKey, pageURL string) (string, error) -} - var validate = based.Lazy[*validator.Validate]{ Fn: func(ctx context.Context) (*validator.Validate, error) { return validator.New(), nil @@ -47,9 +38,7 @@ type ClientBuilder struct { UserAgent string `validate:"required"` TokenStorage TokenStorage `validate:"required"` - CaptchaTokenProvider CaptchaTokenProvider - ConfirmationProvider ConfirmationProvider - Transport http.RoundTripper + Transport http.RoundTripper } func (b ClientBuilder) Build(ctx context.Context) (*Client, error) { @@ -73,8 +62,6 @@ func (b ClientBuilder) Build(ctx context.Context) (*Client, error) { httpClient: &http.Client{ Transport: b.Transport, }, - captchaTokenProvider: b.CaptchaTokenProvider, - confirmationProvider: b.ConfirmationProvider, token: based.NewWriteThroughCached[string, *Tokens]( based.WriteThroughCacheStorageFunc[string, *Tokens]{ LoadFn: b.TokenStorage.LoadTokens, @@ -87,14 +74,12 @@ func (b ClientBuilder) Build(ctx context.Context) (*Client, error) { } type Client struct { - clock based.Clock - phone string - deviceInfo deviceInfo - httpClient *http.Client - captchaTokenProvider CaptchaTokenProvider - confirmationProvider ConfirmationProvider - token *based.WriteThroughCached[*Tokens] - mu based.Locker + clock based.Clock + phone string + deviceInfo deviceInfo + httpClient *http.Client + token *based.WriteThroughCached[*Tokens] + mu based.Locker } func (c *Client) Receipt(ctx context.Context, in *ReceiptIn) (*ReceiptOut, error) { @@ -138,21 +123,12 @@ func (c *Client) ensureToken(ctx context.Context) (string, error) { } func (c *Client) authorize(ctx context.Context) (*Tokens, error) { - var err error - - if c.captchaTokenProvider == nil { - err = multierr.Append(err, errors.New("captcha token provider not set")) - } - - if c.confirmationProvider == nil { - err = multierr.Append(err, errors.New("confirmation provider not set")) - } - - if err != nil { - return nil, err + authorizer := getAuthorizer(ctx) + if authorizer == nil { + return nil, errors.New("authorizer is required, but not set") } - captchaToken, err := c.captchaTokenProvider.GetCaptchaToken(ctx, c.deviceInfo.MetaDetails.UserAgent, captchaSiteKey, captchaPageURL) + captchaToken, err := authorizer.GetCaptchaToken(ctx, c.deviceInfo.MetaDetails.UserAgent, captchaSiteKey, captchaPageURL) if err != nil { return nil, errors.Wrap(err, "get captcha token") } @@ -171,7 +147,7 @@ func (c *Client) authorize(ctx context.Context) (*Tokens, error) { } } - code, err := c.confirmationProvider.GetConfirmationCode(ctx, c.phone) + code, err := authorizer.GetConfirmationCode(ctx, c.phone) if err != nil { return nil, errors.Wrap(err, "get confirmation code") } diff --git a/example/main.go b/example/main.go index c553c17..4c4f313 100644 --- a/example/main.go +++ b/example/main.go @@ -96,12 +96,12 @@ func (s jsonTokenStorage) open(flag int) (*os.File, error) { return file, nil } -type rucaptchaTokenProvider struct { - client *rucaptcha.Client +type authorizer struct { + rucaptchaClient *rucaptcha.Client } -func (p *rucaptchaTokenProvider) GetCaptchaToken(ctx context.Context, userAgent, siteKey, pageURL string) (string, error) { - solved, err := p.client.Solve(ctx, &rucaptcha.YandexSmartCaptchaIn{ +func (a *authorizer) GetCaptchaToken(ctx context.Context, userAgent, siteKey, pageURL string) (string, error) { + solved, err := a.rucaptchaClient.Solve(ctx, &rucaptcha.YandexSmartCaptchaIn{ UserAgent: userAgent, SiteKey: siteKey, PageURL: pageURL, @@ -114,9 +114,7 @@ func (p *rucaptchaTokenProvider) GetCaptchaToken(ctx context.Context, userAgent, return solved.Answer, nil } -type stdinConfirmationProvider struct{} - -func (p stdinConfirmationProvider) GetConfirmationCode(ctx context.Context, phone string) (string, error) { +func (a *authorizer) GetConfirmationCode(ctx context.Context, phone string) (string, error) { reader := bufio.NewReader(os.Stdin) fmt.Printf("Enter confirmation code for %s: ", phone) text, err := reader.ReadString('\n') @@ -143,25 +141,11 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - rucaptchaClient, err := rucaptcha.ClientBuilder{ - Config: rucaptcha.Config{ - Key: config.RucaptchaKey, - }, - }.Build(ctx) - - if err != nil { - panic(err) - } - client, err := lkdr.ClientBuilder{ Phone: config.Phone, Clock: based.StandardClock, DeviceID: config.DeviceID, UserAgent: config.UserAgent, - CaptchaTokenProvider: &rucaptchaTokenProvider{ - client: rucaptchaClient, - }, - ConfirmationProvider: stdinConfirmationProvider{}, TokenStorage: jsonTokenStorage{ path: config.TokensFile, }, @@ -171,6 +155,18 @@ func main() { panic(err) } + rucaptchaClient, err := rucaptcha.ClientBuilder{ + Config: rucaptcha.Config{ + Key: config.RucaptchaKey, + }, + }.Build(ctx) + + if err != nil { + panic(err) + } + + ctx = lkdr.WithAuthorizer(ctx, &authorizer{rucaptchaClient: rucaptchaClient}) + receipts, err := client.Receipt(ctx, &lkdr.ReceiptIn{ Limit: 1, Offset: 0,