Skip to content

Commit

Permalink
Merge pull request #7 from savannahghi/remove-panic
Browse files Browse the repository at this point in the history
chore: remove panics, return error on failure
  • Loading branch information
Salaton committed Nov 3, 2022
2 parents 4914318 + 7daf709 commit e4e6dcc
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 205 deletions.
36 changes: 10 additions & 26 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,33 @@ jobs:
strategy:
fail-fast: true
matrix:
go-version: [1.17.x]
go-version: [1.18.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Install Golang
uses: actions/setup-go@v3
- uses: actions/checkout@v3.1.0
- name: Install Go
uses: actions/setup-go@v3.3.1
with:
go-version: ${{ matrix.go-version }}

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.29

- name: Install Go dependencies
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.37.1
go get -u github.com/kisielk/errcheck
go get -u golang.org/x/lint/golint
go get -u honnef.co/go/tools/cmd/staticcheck
go get -u github.com/axw/gocov/gocov
go get -u github.com/securego/gosec/cmd/gosec
go get -u github.com/ory/go-acc
go get -u github.com/client9/misspell/cmd/misspell
go get -u github.com/gordonklaus/ineffassign
go get github.com/fzipp/gocyclo
go get github.com/stretchr/testify/assert@v1.7.0
go get github.com/ory/go-acc
go get google.golang.org/grpc@v1.38.0
go get google.golang.org/grpc/balancer/grpclb@v1.38.0
go get google.golang.org/api/support/bundler@v0.48.0
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.13.1
go install honnef.co/go/tools/cmd/staticcheck@2022.1
go install github.com/ory/go-acc@latest
go install github.com/axw/gocov/gocov@latest
go install github.com/kisielk/errcheck@latest
- name: Run lint and test
run: |
staticcheck ./...
go fmt $(go list ./... | grep -v /vendor/)
go vet $(go list ./... | grep -v /vendor/)
golint -set_exit_status $(go list ./... | grep -v /vendor/)
errcheck -ignore 'os:.*,' $(go list ./... | grep -v /vendor/)
misspell -error .
gosec ./...
gosec -exclude=G304,G101 ./...
go-acc -o coverage.txt --ignore generated,cmd ./... -- -timeout 60m
grep -v "generated.go" coverage.txt > coverage.out
go tool cover -html=coverage.out -o coverage.html
Expand Down
61 changes: 46 additions & 15 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,40 @@ type client struct {

accessToken string
accessTokenTicker *time.Ticker

authFailed bool
}

// newClient initializes a new SIL comms client instance
func newClient() *client {
func newClient() (*client, error) {
s := &client{
client: &http.Client{
Timeout: time.Second * 10,
},
accessToken: "",
refreshToken: "",
authFailed: false,
}

s.login()
err := s.login()
if err != nil {
return nil, err
}

// set up background routine to update tokens
go s.background()

return s
return s, nil
}

// mustNewClient initializes a new SIL comms client instance
func mustNewClient() *client {
client, err := newClient()
if err != nil {
panic(err)
}

return client
}

// executed as a go routine to update the api tokens when they timeout
Expand All @@ -67,11 +83,17 @@ func (s *client) background() {
select {
case t := <-s.refreshTokenTicker.C:
logrus.Println("SIL Comms Refresh Token updated at: ", t)
s.login()
err := s.login()
if err != nil {
s.authFailed = true
}

case t := <-s.accessTokenTicker.C:
logrus.Println("SIL Comms Access Token updated at: ", t)
s.refreshAccessToken()
err := s.refreshAccessToken()
if err != nil {
s.authFailed = true
}

}
}
Expand Down Expand Up @@ -99,7 +121,7 @@ func (s *client) setRefreshToken(token string) {

// login uses the provided credentials to login to the SIL communications backend
// It obtains the necessary tokens required to make authenticated requests
func (s *client) login() {
func (s *client) login() error {
path := "/auth/token/"
payload := struct {
Email string `json:"email"`
Expand All @@ -112,34 +134,36 @@ func (s *client) login() {
response, err := s.MakeRequest(context.Background(), http.MethodPost, path, nil, payload, false)
if err != nil {
err = fmt.Errorf("failed to make login request: %w", err)
panic(err)
return err
}

if response.StatusCode != http.StatusOK {
err := fmt.Errorf("invalid login response code, got: %d", response.StatusCode)
panic(err)
return err
}

var resp APIResponse
err = json.NewDecoder(response.Body).Decode(&resp)
if err != nil {
err = fmt.Errorf("failed to decode login api response: %w", err)
panic(err)
return err
}

var tokens TokenResponse
err = mapstructure.Decode(resp.Data, &tokens)
if err != nil {
err = fmt.Errorf("failed to decode login data in api response: %w", err)
panic(err)
return err
}

s.setRefreshToken(tokens.Refresh)
s.setAccessToken(tokens.Access)

return nil

}

func (s *client) refreshAccessToken() {
func (s *client) refreshAccessToken() error {
path := "/auth/token/refresh/"
payload := struct {
Refresh string `json:"refresh"`
Expand All @@ -150,34 +174,41 @@ func (s *client) refreshAccessToken() {
response, err := s.MakeRequest(context.Background(), http.MethodPost, path, nil, payload, false)
if err != nil {
err = fmt.Errorf("failed to make refresh request: %w", err)
panic(err)
return err
}

if response.StatusCode != http.StatusOK {
err := fmt.Errorf("invalid refresh token response code, got: %d", response.StatusCode)
panic(err)
return err
}

var resp APIResponse
err = json.NewDecoder(response.Body).Decode(&resp)
if err != nil {
err = fmt.Errorf("failed to decode refresh token api response: %w", err)
panic(err)
return err
}

var tokens TokenResponse
err = mapstructure.Decode(resp.Data, &tokens)
if err != nil {
err = fmt.Errorf("failed to decode refresh token data in api response: %w", err)
panic(err)
return err
}

s.setAccessToken(tokens.Access)

return nil

}

// MakeRequest performs a HTTP request to the provided path and parameters
func (s *client) MakeRequest(ctx context.Context, method, path string, queryParams map[string]string, body interface{}, authorised bool) (*http.Response, error) {
// background refresh failed and the tokens are not valid
if s.authFailed {
return nil, fmt.Errorf("invalid credentials, cannot make request please update")
}

urlPath := fmt.Sprintf("%s%s", BaseURL, path)

var request *http.Request
Expand Down
Loading

0 comments on commit e4e6dcc

Please sign in to comment.