Skip to content

Commit

Permalink
Fixes to make codeclimate happy
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafe Colton committed Dec 3, 2018
1 parent e8f4cd6 commit 83a2758
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 124 deletions.
23 changes: 0 additions & 23 deletions api_method.go

This file was deleted.

164 changes: 66 additions & 98 deletions api.go → client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package zoom
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"log"
"net/http"
Expand All @@ -11,7 +12,6 @@ import (
"time"

"github.com/google/go-querystring/query"
"gopkg.in/dgrijalva/jwt-go.v3"
)

const (
Expand All @@ -33,12 +33,6 @@ var (
defaultClient *Client
)

type apiParams struct {
APIKey string `url:"api_key"`
APISecret string `url:"api_secret"`
DataType string `url:"data_type"`
}

// Client is responsible for making API requests
type Client struct {
Key string
Expand Down Expand Up @@ -81,140 +75,108 @@ func normalizeParams(parameters interface{}) interface{} {
return parameters
}

func requestV2(c *Client, method Method, path string, urlParameters interface{}, dataParameters interface{}, ret interface{}) error {
var buf bytes.Buffer
type requestV2Opts struct {
Client *Client
Method HTTPMethod
Path string
URLParameters interface{}
DataParameters interface{}
Ret interface{}
}

// set client to default if not provided
func initializeDefault(c *Client) *Client {
if c == nil {
if defaultClient == nil {
defaultClient = NewClient(APIKey, APISecret)
}

c = defaultClient
return defaultClient
}

// allow variadic parameters
urlParams := normalizeParams(urlParameters)
dataParams := normalizeParams(dataParameters)
return c
}

// establish JWT token
claims := &jwt.StandardClaims{
Issuer: c.Key,
ExpiresAt: jwt.TimeFunc().Local().Add(time.Second * time.Duration(5000)).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token.Header["alg"] = "HS256"
token.Header["typ"] = "JWT"
ss, err := token.SignedString([]byte(c.Secret))
func (c *Client) executeRequest(opts requestV2Opts) (*http.Response, error) {
client := c.httpClient()
req, err := c.addRequestAuth(c.httpRequest(opts))
if err != nil {
return err
return nil, err
}

// set URL parameters
values, err := query.Values(urlParams)
if err != nil {
return err
}

// set request URL
requestURL := c.endpoint + path + "?"
requestURL += values.Encode()

if Debug {
log.Printf("Request URL: %s", requestURL)
log.Printf("URL Parameters: %s", values.Encode())
}

// create HTTP client and set timeout
client := &http.Client{Transport: c.Transport}
if c.Timeout > 0 {
client.Timeout = c.Timeout
}
return client.Do(req)
}

// encode body parameters if any
if err := json.NewEncoder(&buf).Encode(&dataParams); err != nil {
return err
func (c *Client) addRequestAuth(req *http.Request, err error) (*http.Request, error) {
if err != nil {
return nil, err
}

// create HTTP request
req, err := http.NewRequest(string(method), requestURL, &buf)
// establish JWT token
ss, err := jwtToken(c.Key, c.Secret)
if err != nil {
return err
return nil, err
}

// set JWT Authorization header
req.Header.Add("Authorization", "Bearer "+ss)

// execute HTTP request
resp, err := client.Do(req)
if err != nil {
return err
}

// get HTTP response
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}

if Debug {
log.Printf("Response Body: %s", string(body))
}

if err := checkError(body); err != nil {
return err
}

return json.Unmarshal(body, &ret)
return req, nil
}

func request(c *Client, path string, parameters interface{}, ret interface{}) error {
if c == nil {
if defaultClient == nil {
defaultClient = NewClient(APIKey, APISecret)
}

c = defaultClient
}
func (c *Client) httpRequest(opts requestV2Opts) (*http.Request, error) {
var buf bytes.Buffer

// allow variadic parameters
switch reflect.TypeOf(parameters).Kind() {
case reflect.Slice:
s := reflect.ValueOf(parameters)
if s.Len() == 0 {
parameters = nil
} else {
parameters = s.Index(0).Interface()
}
dataParams := normalizeParams(opts.DataParameters)

// encode body parameters if any
if err := json.NewEncoder(&buf).Encode(&dataParams); err != nil {
return nil, err
}

values, err := query.Values(parameters)
// set URL parameters
values, err := query.Values(normalizeParams(opts.URLParameters))
if err != nil {
return err
return nil, err
}

values.Set("api_key", c.Key)
values.Set("api_secret", c.Secret)
values.Set("data_type", "JSON")
// set request URL
requestURL := c.endpoint + opts.Path + "?" + values.Encode()

requestURL := c.endpoint + path
if Debug {
log.Printf("Request URL: %s", requestURL)
log.Printf("Request Parameters: %s", values.Encode())
log.Printf("URL Parameters: %s", values.Encode())
}

// create HTTP request
req, err := http.NewRequest(string(opts.Method), requestURL, &buf)
if err != nil {
return nil, err
}

return req, nil
}

func (c *Client) httpClient() *http.Client {
client := &http.Client{Transport: c.Transport}
if c.Timeout > 0 {
client.Timeout = c.Timeout
}

// all v1 API endpoints use POST requests
resp, err := client.PostForm(requestURL, values)
return client
}

func (c *Client) requestV2(opts requestV2Opts) error {
// make sure the defaultClient is not nil if we are using it
c = initializeDefault(c)

// execute HTTP request
resp, err := c.executeRequest(opts)
if err != nil {
return err
}

// read HTTP response
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Expand All @@ -225,9 +187,15 @@ func request(c *Client, path string, parameters interface{}, ret interface{}) er
log.Printf("Response Body: %s", string(body))
}

// check for Zoom errors in the response
if err := checkError(body); err != nil {
return err
}

return json.Unmarshal(body, &ret)
// unmarshal the response body into the return object
return json.Unmarshal(body, &opts.Ret)
}

func request(c *Client, path string, parameters interface{}, ret interface{}) error {
return errors.New("this method is DEPRECATED! Use requestV2. This method will be removed when v2 implementation is complete")
}
23 changes: 23 additions & 0 deletions http_method.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package zoom

import "net/http"

// HTTPMethod is the HTTP request method types
type HTTPMethod string

const (
// Get is GET HTTP method
Get HTTPMethod = http.MethodGet

// Post is POST HTTP method
Post HTTPMethod = http.MethodPost

// Put is PUT HTTP method
Put HTTPMethod = http.MethodPut

// Patch is PATCH HTTP method
Patch HTTPMethod = http.MethodPatch

// Delete is DELETE HTTP method
Delete HTTPMethod = http.MethodDelete
)
18 changes: 18 additions & 0 deletions jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package zoom

import (
"time"

"gopkg.in/dgrijalva/jwt-go.v3"
)

func jwtToken(key string, secret string) (string, error) {
claims := &jwt.StandardClaims{
Issuer: key,
ExpiresAt: jwt.TimeFunc().Local().Add(time.Second * time.Duration(5000)).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token.Header["alg"] = "HS256"
token.Header["typ"] = "JWT"
return token.SignedString([]byte(secret))
}
16 changes: 13 additions & 3 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ func ListUsers(opts ...ListUsersOptions) (ListUsersResponse, error) {
// ListUsers calls /user/list, listing all users, using client c
func (c *Client) ListUsers(opts ...ListUsersOptions) (ListUsersResponse, error) {
var ret = ListUsersResponse{}
return ret, requestV2(c, Get, listUsersPath, opts, nil, &ret)
return ret, c.requestV2(requestV2Opts{
Method: Get,
Path: listUsersPath,
URLParameters: opts,
Ret: &ret,
})
}

// GetUserOpts contains options for GetUser
type GetUserOpts struct {
EmailOrID string
EmailOrID string `url:"userId"`
LoginType *UserLoginType `url:"login_type,omitempty"` // use pointer so it can be null
}

Expand All @@ -48,5 +53,10 @@ func GetUser(opts GetUserOpts) (User, error) {
// GetUser calls /users/{userId}, searching for a user by ID or email, using a specific client
func (c *Client) GetUser(opts GetUserOpts) (User, error) {
var ret = User{}
return ret, requestV2(c, Get, fmt.Sprintf(getUserPath, opts.EmailOrID), opts, nil, &ret)
return ret, c.requestV2(requestV2Opts{
Method: Get,
Path: fmt.Sprintf(getUserPath, opts.EmailOrID),
URLParameters: opts,
Ret: &ret,
})
}

0 comments on commit 83a2758

Please sign in to comment.