Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
vcraescu committed Jan 7, 2024
0 parents commit 5f3b03d
Show file tree
Hide file tree
Showing 14 changed files with 590 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.21

- name: Test
run: make test
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
.env*
!.env.dist

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum
creds/
data/
.serverless
bin/
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: test

test:
go test ./...
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# OblioAPI ![](https://github.com/vcraescu/go-oblio-api/actions/workflows/go.yml/badge.svg)

## How to run the tests

`make test`
59 changes: 59 additions & 0 deletions api_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package oblio

import (
"context"
"fmt"
"net/http"
)

type authorizeTokenRequest struct {
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
}

func (r *authorizeTokenRequest) Validate() error {
if r.ClientID == "" {
return fmt.Errorf("clientID is empty: %w", ErrInvalidArgument)
}

if r.ClientSecret == "" {
return fmt.Errorf("clientSecret is empty: %w", ErrInvalidArgument)
}

return nil
}

type AuthorizeTokenResponse struct {
AccessToken string `json:"access_token,omitempty"`
ExpiresIn string `json:"expires_in,omitempty"`
TokenType string `json:"token_type,omitempty"`
Scope string `json:"scope,omitempty"`
RequestTime string `json:"request_time,omitempty"`
}

func (c *Client) GetAuthorizeToken(ctx context.Context) (AuthorizeTokenResponse, error) {
in := authorizeTokenRequest{
ClientID: c.clientID,
ClientSecret: c.clientSecret,
}
out := AuthorizeTokenResponse{}

if err := in.Validate(); err != nil {
return out, err
}

req, err := c.requestBuilder.
WithMethod(http.MethodPost).
WithPath("/authorize/token").
WithParams(in).
Build(ctx)
if err != nil {
return out, fmt.Errorf("build request: %w", err)
}

if err := c.do(req, &out); err != nil {
return out, fmt.Errorf("do: %w", err)
}

return out, nil
}
77 changes: 77 additions & 0 deletions api_auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package oblio_test

import (
"context"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/vcraescu/go-oblio-api"
"github.com/vcraescu/go-oblio-api/internal"
"net/http"
"testing"
)

func TestClient_GetAuthorizeToken(t *testing.T) {
t.Parallel()

type fields struct {
clientID string
clientSecret string
}

tests := []struct {
name string
fields fields
want oblio.AuthorizeTokenResponse
wantReq HTTPRequestAssertionFunc
wantErr assert.ErrorAssertionFunc
}{
{
name: "success",
fields: fields{
clientID: "client-id",
clientSecret: "client-secret",
},
want: oblio.AuthorizeTokenResponse{
AccessToken: "67d6f8817c28d698bdae35728c7a30b02a75bd4d",
ExpiresIn: "3600",
TokenType: "Bearer",
RequestTime: "1540471129",
},
wantReq: func(t *testing.T, got *http.Request) bool {
want := &http.Request{
Method: http.MethodPost,
RequestURI: "/authorize/token?client_id=client-id&client_secret=client-secret",
Header: http.Header{
internal.ContentTypeHeaderName: []string{internal.FormURLEncodedHeaderValue},
},
}

return assert.Equal(t, want.RequestURI, got.RequestURI) &&
assert.Equal(
t, want.Header[internal.ContentTypeHeaderName], got.Header[internal.ContentTypeHeaderName]) &&
assert.Equal(t, want.Method, got.Method)
},
},
}

for _, tt := range tests {
tt := tt

t.Run(tt.name, func(t *testing.T) {
t.Parallel()

baseURL := StartServer(t, tt.wantReq)
client := oblio.NewClient(tt.fields.clientID, tt.fields.clientSecret, oblio.WithBaseURL(baseURL))
got, err := client.GetAuthorizeToken(context.Background())

if tt.wantErr != nil {
tt.wantErr(t, err)

return
}

require.NoError(t, err)
require.Equal(t, tt.want, got)
})
}
}
48 changes: 48 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package oblio

import (
"encoding/json"
"fmt"
"github.com/vcraescu/go-oblio-api/internal"
"net/http"
)

const BaseURL = "https://www.oblio.eu/api/"

type Client struct {
clientID string
clientSecret string
baseURL string
httpClient *http.Client
requestBuilder *internal.RequestBuilder
}

func NewClient(clientID, clientSecret string, opts ...Option) *Client {
options := newOptions(opts)

return &Client{
clientID: clientID,
clientSecret: clientSecret,
baseURL: options.baseURL,
httpClient: options.client,
requestBuilder: internal.NewRequestBuilder(options.baseURL),
}
}

func (c *Client) do(req *http.Request, out any) error {
resp, err := c.httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
return UnmarshalErrorResponse(resp)
}

if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
return fmt.Errorf("decode: %w", err)
}

return nil
}
38 changes: 38 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package oblio

import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
)

var (
ErrInvalidArgument = errors.New("invalid argument")
)

type ErrorResponse struct {
Status int `json:"status,omitempty"`
Message string `json:"statusMessage,omitempty"`
}

func UnmarshalErrorResponse(resp *http.Response) *ErrorResponse {
defer resp.Body.Close()

out := &ErrorResponse{
Status: resp.StatusCode,
Message: resp.Status,
}

if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
b, _ := io.ReadAll(resp.Body)
out.Message = string(b)
}

return out
}

func (e *ErrorResponse) Error() string {
return fmt.Sprintf("status code: %d, message: %s", e.Status, e.Message)
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/vcraescu/go-oblio-api

go 1.21

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.1 // indirect
github.com/stretchr/testify v1.8.4 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
19 changes: 19 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading

0 comments on commit 5f3b03d

Please sign in to comment.