From 780273b16e4a1dbe9cac553da277cb4fe022f39f Mon Sep 17 00:00:00 2001 From: edmarSoaress Date: Fri, 16 Feb 2024 11:31:45 -0300 Subject: [PATCH 1/4] add oauth implementation --- examples/apis/oauth/create/main.go | 31 +++ .../apis/oauth/getauthorizationurl/main.go | 28 +++ examples/apis/oauth/main.go | 28 +++ examples/apis/oauth/refresh/main.go | 38 +++ pkg/oauth/client.go | 98 ++++++++ pkg/oauth/client_test.go | 228 ++++++++++++++++++ pkg/oauth/request.go | 16 ++ pkg/oauth/response.go | 11 + pkg/user/{user_test.go => client_test.go} | 0 resources/mocks/oauth/response.json | 11 + test/integration/oauth/oauth_test.go | 64 +++++ 11 files changed, 553 insertions(+) create mode 100644 examples/apis/oauth/create/main.go create mode 100644 examples/apis/oauth/getauthorizationurl/main.go create mode 100644 examples/apis/oauth/main.go create mode 100644 examples/apis/oauth/refresh/main.go create mode 100644 pkg/oauth/client.go create mode 100644 pkg/oauth/client_test.go create mode 100644 pkg/oauth/request.go create mode 100644 pkg/oauth/response.go rename pkg/user/{user_test.go => client_test.go} (100%) create mode 100644 resources/mocks/oauth/response.json create mode 100644 test/integration/oauth/oauth_test.go diff --git a/examples/apis/oauth/create/main.go b/examples/apis/oauth/create/main.go new file mode 100644 index 00000000..2fd507f3 --- /dev/null +++ b/examples/apis/oauth/create/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "fmt" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/oauth" +) + +func main() { + accessToken := "APP_USR-175307012991241-090809-79832955e82d14ef55e4bd9fe75d354a-213761027" + + cfg, err := config.New(accessToken) + if err != nil { + fmt.Println(err) + return + } + + client := oauth.NewClient(cfg) + authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" + redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + + credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(credential) +} diff --git a/examples/apis/oauth/getauthorizationurl/main.go b/examples/apis/oauth/getauthorizationurl/main.go new file mode 100644 index 00000000..775d4f7e --- /dev/null +++ b/examples/apis/oauth/getauthorizationurl/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "context" + "fmt" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/oauth" +) + +func main() { + accessToken := "{{ACCESS_TOKEN}}" + + cfg, err := config.New(accessToken) + if err != nil { + fmt.Println(err) + return + } + + client := oauth.NewClient(cfg) + + clientID := "175307012991241" + redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + + url := client.GetAuthorizationURL(context.Background(), clientID, redirectURI) + + fmt.Println(url) +} diff --git a/examples/apis/oauth/main.go b/examples/apis/oauth/main.go new file mode 100644 index 00000000..85b7aaed --- /dev/null +++ b/examples/apis/oauth/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "context" + "fmt" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/user" +) + +func main() { + accessToken := "{{ACCESS_TOKEN}}" + + cfg, err := config.New(accessToken) + if err != nil { + fmt.Println(err) + return + } + + userClient := user.NewClient(cfg) + user, err := userClient.Get(context.Background()) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(user) +} diff --git a/examples/apis/oauth/refresh/main.go b/examples/apis/oauth/refresh/main.go new file mode 100644 index 00000000..c10bb4a1 --- /dev/null +++ b/examples/apis/oauth/refresh/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "context" + "fmt" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/oauth" +) + +func main() { + accessToken := "APP_USR-175307012991241-090809-79832955e82d14ef55e4bd9fe75d354a-213761027" + + cfg, err := config.New(accessToken) + if err != nil { + fmt.Println(err) + return + } + + client := oauth.NewClient(cfg) + authorizationCode := "TG-65cf4dd1c7cada00016007e7-213761027" + redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + + credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + if err != nil { + fmt.Println(err) + return + } + + refreshToken := credential.RefreshToken + credential, err = client.Refresh(context.Background(), refreshToken) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(credential) +} diff --git a/pkg/oauth/client.go b/pkg/oauth/client.go new file mode 100644 index 00000000..c6289fd2 --- /dev/null +++ b/pkg/oauth/client.go @@ -0,0 +1,98 @@ +package oauth + +import ( + "context" + "net/url" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/internal/httpclient" +) + +const ( + baseUrl = "https://api.mercadopago.com/oauth/token" + urlOAuth = "https://auth.mercadopago.com/authorization" +) + +// Client contains the method to interact with the OAuth API. +type Client interface { + + // Create Oauth credentials to operate on behalf of a seller + // It is a Post request to the endpoint: "https://api.mercadopago.com/oauth/token" + // Reference: https://www.mercadopago.com.br/developers/en/reference/oauth/_oauth_token/post + Create(ctx context.Context, authorizationCode, redirectURI string) (*Response, error) + + // Get URL for Oauth authorization. + GetAuthorizationURL(ctx context.Context, clientID, redirectURI string) string + + // Refresh token received when you create credentials. + // It is a Post request to the endpoint: "https://api.mercadopago.com/oauth/token" + // Reference: https://www.mercadopago.com.br/developers/en/reference/oauth/_oauth_token/post + Refresh(ctx context.Context, refreshToken string) (*Response, error) +} + +// client is the implementation of Client. +type client struct { + cfg *config.Config +} + +// NewClient returns a new User API Client. +func NewClient(c *config.Config) Client { + return &client{ + cfg: c, + } +} + +func (c *client) Create(ctx context.Context, authorizationCode, redirectURI string) (*Response, error) { + request := &Request{ + ClientSecret: c.cfg.AccessToken, + Code: authorizationCode, + RedirectURI: redirectURI, + GrantType: "authorization_code", + } + + res, err := httpclient.Post[Response](ctx, c.cfg, baseUrl, request) + if err != nil { + return nil, err + } + + return res, nil +} + +func (c *client) GetAuthorizationURL(ctx context.Context, clientID, redirectURI string) string { + params := map[string]string{ + "client_id": clientID, + "response_type": "code", + "platform_id": "mp", + "redirect_uri": redirectURI, + } + + host, err := url.Parse(urlOAuth) + if err != nil { + return "" + } + + queryParams := url.Values{} + + for k, v := range params { + queryParams.Add(k, v) + } + + host.RawQuery = queryParams.Encode() + + return host.String() +} + +func (c *client) Refresh(ctx context.Context, refreshToken string) (*Response, error) { + request := &RefreshTokenRequest{ + ClientSecret: c.cfg.AccessToken, + RefreshToken: refreshToken, + GrantType: "refresh_token", + } + + res, err := httpclient.Post[Response](ctx, c.cfg, baseUrl, request) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/pkg/oauth/client_test.go b/pkg/oauth/client_test.go new file mode 100644 index 00000000..9e965d2e --- /dev/null +++ b/pkg/oauth/client_test.go @@ -0,0 +1,228 @@ +package oauth + +import ( + "context" + "fmt" + "io" + "net/http" + "os" + "reflect" + "strings" + "testing" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/internal/httpclient" +) + +var ( + oauthResponseJSON, _ = os.Open("../../resources/mocks/oauth/response.json") + oauthResponse, _ = io.ReadAll(oauthResponseJSON) +) + +func TestCreate(t *testing.T) { + type fields struct { + config *config.Config + } + type args struct { + ctx context.Context + } + tests := []struct { + name string + fields fields + args args + want *Response + wantErr string + }{ + { + name: "should_return_error_when_send_request", + fields: fields{ + config: &config.Config{ + Requester: &httpclient.Mock{ + DoMock: func(req *http.Request) (*http.Response, error) { + return nil, fmt.Errorf("some error") + }, + }, + }, + }, + args: args{ + ctx: context.Background(), + }, + want: nil, + wantErr: "transport level error: some error", + }, + { + name: "should_return_response", + fields: fields{ + config: &config.Config{ + Requester: &httpclient.Mock{ + DoMock: func(req *http.Request) (*http.Response, error) { + stringReader := strings.NewReader(string(oauthResponse)) + stringReadCloser := io.NopCloser(stringReader) + return &http.Response{ + Body: stringReadCloser, + }, nil + }, + }, + }, + }, + args: args{ + ctx: context.Background(), + }, + want: &Response{ + AccessToken: "APP_USR-1223334455", + Scope: "offline_access payments read write", + RefreshToken: "TG-65cf4eed634", + PublicKey: "APP_USR-5b5b91b7", + TokenType: "Bearer", + LiveMode: true, + ExpiresIn: 15552000, + }, + wantErr: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &client{ + cfg: tt.fields.config, + } + got, err := c.Create(tt.args.ctx, "TG-65cf4eed634", "http://test.com") + gotErr := "" + if err != nil { + gotErr = err.Error() + } + + if gotErr != tt.wantErr { + t.Errorf("client.Create() error = %v, wantErr %v", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("client.Create() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRefresh(t *testing.T) { + type fields struct { + config *config.Config + } + type args struct { + ctx context.Context + } + tests := []struct { + name string + fields fields + args args + want *Response + wantErr string + }{ + { + name: "should_return_error_when_send_request", + fields: fields{ + config: &config.Config{ + Requester: &httpclient.Mock{ + DoMock: func(req *http.Request) (*http.Response, error) { + return nil, fmt.Errorf("some error") + }, + }, + }, + }, + args: args{ + ctx: context.Background(), + }, + want: nil, + wantErr: "transport level error: some error", + }, + { + name: "should_return_response", + fields: fields{ + config: &config.Config{ + Requester: &httpclient.Mock{ + DoMock: func(req *http.Request) (*http.Response, error) { + stringReader := strings.NewReader(string(oauthResponse)) + stringReadCloser := io.NopCloser(stringReader) + return &http.Response{ + Body: stringReadCloser, + }, nil + }, + }, + }, + }, + args: args{ + ctx: context.Background(), + }, + want: &Response{ + AccessToken: "APP_USR-1223334455", + Scope: "offline_access payments read write", + RefreshToken: "TG-65cf4eed634", + PublicKey: "APP_USR-5b5b91b7", + TokenType: "Bearer", + LiveMode: true, + ExpiresIn: 15552000, + }, + wantErr: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &client{ + cfg: tt.fields.config, + } + got, err := c.Refresh(tt.args.ctx, "TG-65cf4eed634") + gotErr := "" + if err != nil { + gotErr = err.Error() + } + + if gotErr != tt.wantErr { + t.Errorf("client.Create() error = %v, wantErr %v", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("client.Create() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetAuthorizationURL(t *testing.T) { + type fields struct { + config *config.Config + } + type args struct { + ctx context.Context + appID string + redirectURI string + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "should_return_authorization_url", + fields: fields{ + config: &config.Config{ + AccessToken: "accessToken", + }, + }, + args: args{ + ctx: context.Background(), + appID: "appID", + redirectURI: "redirectURI", + }, + want: "https://auth.mercadopago.com/authorization?client_id=appID&platform_id=mp&redirect_uri=redirectURI&response_type=code", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &client{ + cfg: tt.fields.config, + } + got := c.GetAuthorizationURL(tt.args.ctx, tt.args.appID, tt.args.redirectURI) + + if got != tt.want { + t.Errorf("client.getAuthorizationURL() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/oauth/request.go b/pkg/oauth/request.go new file mode 100644 index 00000000..eb36af1d --- /dev/null +++ b/pkg/oauth/request.go @@ -0,0 +1,16 @@ +package oauth + +type Request struct { + GrantType string `json:"grant_type,omitempty"` + ClientSecret string `json:"client_secret,omitempty"` + ClientID string `json:"client_id,omitempty"` + Code string `json:"code,omitempty"` + RedirectURI string `json:"redirect_uri,omitempty"` +} + +type RefreshTokenRequest struct { + GrantType string `json:"grant_type,omitempty"` + ClientSecret string `json:"client_secret,omitempty"` + ClientID string `json:"client_id,omitempty"` + RefreshToken string `json:"refresh_token,omitempty"` +} diff --git a/pkg/oauth/response.go b/pkg/oauth/response.go new file mode 100644 index 00000000..c4b1c33a --- /dev/null +++ b/pkg/oauth/response.go @@ -0,0 +1,11 @@ +package oauth + +type Response struct { + AccessToken string `json:"access_token"` + Scope string `json:"scope"` + RefreshToken string `json:"refresh_token"` + PublicKey string `json:"public_key"` + TokenType string `json:"token_type"` + LiveMode bool `json:"live_mode"` + ExpiresIn int64 `json:"expires_in"` +} diff --git a/pkg/user/user_test.go b/pkg/user/client_test.go similarity index 100% rename from pkg/user/user_test.go rename to pkg/user/client_test.go diff --git a/resources/mocks/oauth/response.json b/resources/mocks/oauth/response.json new file mode 100644 index 00000000..01018ae8 --- /dev/null +++ b/resources/mocks/oauth/response.json @@ -0,0 +1,11 @@ +{ + "access_token": "APP_USR-1223334455", + "scope": "offline_access payments read write", + "refresh_token": "TG-65cf4eed634", + "public_key": "APP_USR-5b5b91b7", + "token_type": "Bearer", + "live_mode": true, + "expires_in": 15552000 +} + + diff --git a/test/integration/oauth/oauth_test.go b/test/integration/oauth/oauth_test.go new file mode 100644 index 00000000..caf377ee --- /dev/null +++ b/test/integration/oauth/oauth_test.go @@ -0,0 +1,64 @@ +package integration + +import ( + "context" + "os" + "testing" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/oauth" +) + +func TestUser(t *testing.T) { + + t.Run("should_create_credentails", func(t *testing.T) { + cfg, err := config.New(os.Getenv("ACCESS_TOKEN")) + if err != nil { + t.Fatal(err) + } + + client := oauth.NewClient(cfg) + authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" + redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + + credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + + if credential == nil { + t.Error("credential can't be nil") + } + if err != nil { + t.Errorf(err.Error()) + } + }) + + t.Run("should_refresh_token", func(t *testing.T) { + cfg, err := config.New(os.Getenv("ACCESS_TOKEN")) + if err != nil { + t.Fatal(err) + } + + client := oauth.NewClient(cfg) + authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" + redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + + credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + + if credential == nil { + t.Error("res can't be nil") + return + } + if err != nil { + t.Errorf(err.Error()) + } + + refreshToken := credential.RefreshToken + credential, err = client.Refresh(context.Background(), refreshToken) + + if credential == nil { + t.Error("credential can't be nil") + } + if err != nil { + t.Errorf(err.Error()) + } + }) +} From 83736e5d5cb7cdad651940d57be72949e259c7c1 Mon Sep 17 00:00:00 2001 From: edmarSoaress Date: Fri, 16 Feb 2024 13:53:58 -0300 Subject: [PATCH 2/4] add comments in struct and adjust tests --- examples/apis/oauth/create/main.go | 10 +++--- .../apis/oauth/getauthorizationurl/main.go | 8 ++--- examples/apis/oauth/main.go | 28 ---------------- examples/apis/oauth/refresh/main.go | 14 ++++---- pkg/oauth/client.go | 32 +++++++++---------- pkg/oauth/client_test.go | 16 +++++----- pkg/oauth/request.go | 4 +-- pkg/oauth/response.go | 1 + test/integration/oauth/oauth_test.go | 30 ++++++++--------- 9 files changed, 58 insertions(+), 85 deletions(-) delete mode 100644 examples/apis/oauth/main.go diff --git a/examples/apis/oauth/create/main.go b/examples/apis/oauth/create/main.go index 2fd507f3..981a14bd 100644 --- a/examples/apis/oauth/create/main.go +++ b/examples/apis/oauth/create/main.go @@ -9,7 +9,7 @@ import ( ) func main() { - accessToken := "APP_USR-175307012991241-090809-79832955e82d14ef55e4bd9fe75d354a-213761027" + accessToken := "{{ACCESS_TOKEN}}" cfg, err := config.New(accessToken) if err != nil { @@ -18,14 +18,14 @@ func main() { } client := oauth.NewClient(cfg) - authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" - redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + authorizationCode := "{{AUTHORIZATION_CODE}}" + redirectURI := "{{REDIRECT_URI}}" - credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + cred, err := client.Create(context.Background(), authorizationCode, redirectURI) if err != nil { fmt.Println(err) return } - fmt.Println(credential) + fmt.Println(cred) } diff --git a/examples/apis/oauth/getauthorizationurl/main.go b/examples/apis/oauth/getauthorizationurl/main.go index 775d4f7e..8d6d77d9 100644 --- a/examples/apis/oauth/getauthorizationurl/main.go +++ b/examples/apis/oauth/getauthorizationurl/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "github.com/mercadopago/sdk-go/pkg/config" @@ -19,10 +18,11 @@ func main() { client := oauth.NewClient(cfg) - clientID := "175307012991241" - redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + clientID := "{{CLIENT_ID}}" + redirectURI := "{{REDIRECT_URI}}" + state := "state" - url := client.GetAuthorizationURL(context.Background(), clientID, redirectURI) + url := client.GetAuthorizationURL(clientID, redirectURI, state) fmt.Println(url) } diff --git a/examples/apis/oauth/main.go b/examples/apis/oauth/main.go deleted file mode 100644 index 85b7aaed..00000000 --- a/examples/apis/oauth/main.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "context" - "fmt" - - "github.com/mercadopago/sdk-go/pkg/config" - "github.com/mercadopago/sdk-go/pkg/user" -) - -func main() { - accessToken := "{{ACCESS_TOKEN}}" - - cfg, err := config.New(accessToken) - if err != nil { - fmt.Println(err) - return - } - - userClient := user.NewClient(cfg) - user, err := userClient.Get(context.Background()) - if err != nil { - fmt.Println(err) - return - } - - fmt.Println(user) -} diff --git a/examples/apis/oauth/refresh/main.go b/examples/apis/oauth/refresh/main.go index c10bb4a1..97c18d08 100644 --- a/examples/apis/oauth/refresh/main.go +++ b/examples/apis/oauth/refresh/main.go @@ -9,7 +9,7 @@ import ( ) func main() { - accessToken := "APP_USR-175307012991241-090809-79832955e82d14ef55e4bd9fe75d354a-213761027" + accessToken := "{{ACCESS_TOKEN}}" cfg, err := config.New(accessToken) if err != nil { @@ -18,21 +18,21 @@ func main() { } client := oauth.NewClient(cfg) - authorizationCode := "TG-65cf4dd1c7cada00016007e7-213761027" - redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + authorizationCode := "{{AUTHORIZATION_CODE}}" + redirectURI := "{{REDIRECT_URI}}" - credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + cred, err := client.Create(context.Background(), authorizationCode, redirectURI) if err != nil { fmt.Println(err) return } - refreshToken := credential.RefreshToken - credential, err = client.Refresh(context.Background(), refreshToken) + refreshToken := cred.RefreshToken + cred, err = client.Refresh(context.Background(), refreshToken) if err != nil { fmt.Println(err) return } - fmt.Println(credential) + fmt.Println(cred) } diff --git a/pkg/oauth/client.go b/pkg/oauth/client.go index c6289fd2..caaf9005 100644 --- a/pkg/oauth/client.go +++ b/pkg/oauth/client.go @@ -5,28 +5,28 @@ import ( "net/url" "github.com/mercadopago/sdk-go/pkg/config" - "github.com/mercadopago/sdk-go/pkg/internal/httpclient" + "github.com/mercadopago/sdk-go/pkg/internal/baseclient" ) const ( - baseUrl = "https://api.mercadopago.com/oauth/token" - urlOAuth = "https://auth.mercadopago.com/authorization" + baseUrl = "https://api.mercadopago.com/oauth/token" + urlAuth = "https://auth.mercadopago.com/authorization" ) -// Client contains the method to interact with the OAuth API. +// Client contains the method to interact with the Oauth API. type Client interface { - // Create Oauth credentials to operate on behalf of a seller - // It is a Post request to the endpoint: "https://api.mercadopago.com/oauth/token" - // Reference: https://www.mercadopago.com.br/developers/en/reference/oauth/_oauth_token/post + // Create oauth credentials to operate on behalf of a seller + // It is a post request to the endpoint: "https://api.mercadopago.com/oauth/token" + // Reference: https://www.mercadopago.com/developers/en/reference/oauth/_oauth_token/post Create(ctx context.Context, authorizationCode, redirectURI string) (*Response, error) - // Get URL for Oauth authorization. - GetAuthorizationURL(ctx context.Context, clientID, redirectURI string) string + // Get url for oauth authorization. + GetAuthorizationURL(clientID, redirectURI, state string) string // Refresh token received when you create credentials. - // It is a Post request to the endpoint: "https://api.mercadopago.com/oauth/token" - // Reference: https://www.mercadopago.com.br/developers/en/reference/oauth/_oauth_token/post + // It is a post request to the endpoint: "https://api.mercadopago.com/oauth/token" + // Reference: https://www.mercadopago.com/developers/en/reference/oauth/_oauth_token/post Refresh(ctx context.Context, refreshToken string) (*Response, error) } @@ -35,7 +35,7 @@ type client struct { cfg *config.Config } -// NewClient returns a new User API Client. +// NewClient returns a new Oauth API Client. func NewClient(c *config.Config) Client { return &client{ cfg: c, @@ -50,7 +50,7 @@ func (c *client) Create(ctx context.Context, authorizationCode, redirectURI stri GrantType: "authorization_code", } - res, err := httpclient.Post[Response](ctx, c.cfg, baseUrl, request) + res, err := baseclient.Post[*Response](ctx, c.cfg, baseUrl, request) if err != nil { return nil, err } @@ -58,7 +58,7 @@ func (c *client) Create(ctx context.Context, authorizationCode, redirectURI stri return res, nil } -func (c *client) GetAuthorizationURL(ctx context.Context, clientID, redirectURI string) string { +func (c *client) GetAuthorizationURL(clientID, redirectURI, state string) string { params := map[string]string{ "client_id": clientID, "response_type": "code", @@ -66,7 +66,7 @@ func (c *client) GetAuthorizationURL(ctx context.Context, clientID, redirectURI "redirect_uri": redirectURI, } - host, err := url.Parse(urlOAuth) + host, err := url.Parse(urlAuth) if err != nil { return "" } @@ -89,7 +89,7 @@ func (c *client) Refresh(ctx context.Context, refreshToken string) (*Response, e GrantType: "refresh_token", } - res, err := httpclient.Post[Response](ctx, c.cfg, baseUrl, request) + res, err := baseclient.Post[*Response](ctx, c.cfg, baseUrl, request) if err != nil { return nil, err } diff --git a/pkg/oauth/client_test.go b/pkg/oauth/client_test.go index 9e965d2e..76224ddc 100644 --- a/pkg/oauth/client_test.go +++ b/pkg/oauth/client_test.go @@ -174,10 +174,10 @@ func TestRefresh(t *testing.T) { } if gotErr != tt.wantErr { - t.Errorf("client.Create() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("client.Refresh() error = %v, wantErr %v", err, tt.wantErr) } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("client.Create() = %v, want %v", got, tt.want) + t.Errorf("client.Refresh() = %v, want %v", got, tt.want) } }) } @@ -188,9 +188,9 @@ func TestGetAuthorizationURL(t *testing.T) { config *config.Config } type args struct { - ctx context.Context - appID string + clientID string redirectURI string + state string } tests := []struct { name string @@ -206,11 +206,11 @@ func TestGetAuthorizationURL(t *testing.T) { }, }, args: args{ - ctx: context.Background(), - appID: "appID", + clientID: "323123123", redirectURI: "redirectURI", + state: "state", }, - want: "https://auth.mercadopago.com/authorization?client_id=appID&platform_id=mp&redirect_uri=redirectURI&response_type=code", + want: "https://auth.mercadopago.com/authorization?client_id=323123123&platform_id=mp&redirect_uri=redirectURI&response_type=code", }, } for _, tt := range tests { @@ -218,7 +218,7 @@ func TestGetAuthorizationURL(t *testing.T) { c := &client{ cfg: tt.fields.config, } - got := c.GetAuthorizationURL(tt.args.ctx, tt.args.appID, tt.args.redirectURI) + got := c.GetAuthorizationURL(tt.args.clientID, tt.args.redirectURI, tt.args.state) if got != tt.want { t.Errorf("client.getAuthorizationURL() = %v, want %v", got, tt.want) diff --git a/pkg/oauth/request.go b/pkg/oauth/request.go index eb36af1d..aa0a5ebb 100644 --- a/pkg/oauth/request.go +++ b/pkg/oauth/request.go @@ -1,16 +1,16 @@ package oauth +// Request represents credential information to perform a create credential request. type Request struct { GrantType string `json:"grant_type,omitempty"` ClientSecret string `json:"client_secret,omitempty"` - ClientID string `json:"client_id,omitempty"` Code string `json:"code,omitempty"` RedirectURI string `json:"redirect_uri,omitempty"` } +// RefreshTokenRequest represents credential information to perform a refresh credential request. type RefreshTokenRequest struct { GrantType string `json:"grant_type,omitempty"` ClientSecret string `json:"client_secret,omitempty"` - ClientID string `json:"client_id,omitempty"` RefreshToken string `json:"refresh_token,omitempty"` } diff --git a/pkg/oauth/response.go b/pkg/oauth/response.go index c4b1c33a..a86ae257 100644 --- a/pkg/oauth/response.go +++ b/pkg/oauth/response.go @@ -1,5 +1,6 @@ package oauth +// Response represents credential information for an Oauth authorization type Response struct { AccessToken string `json:"access_token"` Scope string `json:"scope"` diff --git a/test/integration/oauth/oauth_test.go b/test/integration/oauth/oauth_test.go index caf377ee..a9488b2c 100644 --- a/test/integration/oauth/oauth_test.go +++ b/test/integration/oauth/oauth_test.go @@ -9,21 +9,20 @@ import ( "github.com/mercadopago/sdk-go/pkg/oauth" ) -func TestUser(t *testing.T) { - - t.Run("should_create_credentails", func(t *testing.T) { +func TestOauth(t *testing.T) { + t.Run("should_create_credentials", func(t *testing.T) { cfg, err := config.New(os.Getenv("ACCESS_TOKEN")) if err != nil { t.Fatal(err) } client := oauth.NewClient(cfg) - authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" - redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" + authorizationCode := "authorization_code" + redirectURI := "redirect_uri" - credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + cred, err := client.Create(context.Background(), authorizationCode, redirectURI) - if credential == nil { + if cred == nil { t.Error("credential can't be nil") } if err != nil { @@ -38,23 +37,24 @@ func TestUser(t *testing.T) { } client := oauth.NewClient(cfg) - authorizationCode := "TG-65cf441cb3cf3e000144dfbb-213761027" - redirectURI := "https://httpdump.app/inspect/e340c21c-3afa-45a2-a6c7-a859cafcb7d2" - credential, err := client.Create(context.Background(), authorizationCode, redirectURI) + authorizationCode := "authorization_code" + redirectURI := "redirect_uri" + + cred, err := client.Create(context.Background(), authorizationCode, redirectURI) - if credential == nil { - t.Error("res can't be nil") + if cred == nil { + t.Error("credential can't be nil") return } if err != nil { t.Errorf(err.Error()) } - refreshToken := credential.RefreshToken - credential, err = client.Refresh(context.Background(), refreshToken) + refreshToken := cred.RefreshToken + cred, err = client.Refresh(context.Background(), refreshToken) - if credential == nil { + if cred == nil { t.Error("credential can't be nil") } if err != nil { From ee39704e4a8fc9c9950f158fdd9355a9e1581f64 Mon Sep 17 00:00:00 2001 From: edmarSoaress Date: Fri, 16 Feb 2024 14:36:38 -0300 Subject: [PATCH 3/4] rename baseUrl to urlBase --- pkg/oauth/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/oauth/client.go b/pkg/oauth/client.go index caaf9005..bdf5a7ac 100644 --- a/pkg/oauth/client.go +++ b/pkg/oauth/client.go @@ -9,7 +9,7 @@ import ( ) const ( - baseUrl = "https://api.mercadopago.com/oauth/token" + urlBase = "https://api.mercadopago.com/oauth/token" urlAuth = "https://auth.mercadopago.com/authorization" ) @@ -50,7 +50,7 @@ func (c *client) Create(ctx context.Context, authorizationCode, redirectURI stri GrantType: "authorization_code", } - res, err := baseclient.Post[*Response](ctx, c.cfg, baseUrl, request) + res, err := baseclient.Post[*Response](ctx, c.cfg, urlBase, request) if err != nil { return nil, err } @@ -89,7 +89,7 @@ func (c *client) Refresh(ctx context.Context, refreshToken string) (*Response, e GrantType: "refresh_token", } - res, err := baseclient.Post[*Response](ctx, c.cfg, baseUrl, request) + res, err := baseclient.Post[*Response](ctx, c.cfg, urlBase, request) if err != nil { return nil, err } From 645c804c09214143827fe55215c8d41c62a39e22 Mon Sep 17 00:00:00 2001 From: edmarSoaress Date: Fri, 16 Feb 2024 18:01:35 -0300 Subject: [PATCH 4/4] add code review suggestion --- pkg/oauth/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/oauth/client.go b/pkg/oauth/client.go index bdf5a7ac..2df773fb 100644 --- a/pkg/oauth/client.go +++ b/pkg/oauth/client.go @@ -66,7 +66,7 @@ func (c *client) GetAuthorizationURL(clientID, redirectURI, state string) string "redirect_uri": redirectURI, } - host, err := url.Parse(urlAuth) + parsedURL, err := url.Parse(urlAuth) if err != nil { return "" } @@ -77,9 +77,9 @@ func (c *client) GetAuthorizationURL(clientID, redirectURI, state string) string queryParams.Add(k, v) } - host.RawQuery = queryParams.Encode() + parsedURL.RawQuery = queryParams.Encode() - return host.String() + return parsedURL.String() } func (c *client) Refresh(ctx context.Context, refreshToken string) (*Response, error) {