Skip to content

Commit

Permalink
JWT is deprecated by Zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
fceller committed Sep 18, 2023
1 parent 64b6126 commit ee4c801
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 66 deletions.
32 changes: 10 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ This terraform provider allows to perform Create ,Read ,Update, Delete, Import a

1. Go to [Zoom Marketplace](https://marketplace.zoom.us/)<br>
2. Click on `Build App`. For our purpose we need to make a JWT App. <br>
3. Follow this [Create JWT Zoom App](https://marketplace.zoom.us/docs/guides/build/jwt-app) website to make an app. <br>
4. This app will provide us with the zoom_api_secret, zoom_api_key, and ZOOM_TOKEN which will be needed to configure our
provider and make request. <br>
3. Create a server-to-server application.
4. This app will provide us with the ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, and ZOOM_CLIENT_SECRET which will be needed
to configure our provider and make request. <br>

## Building the Provider

Expand Down Expand Up @@ -119,8 +119,9 @@ terraform {
}
provider "zoom" {
zoom_api_key = "[ZOOM_API_KEY]"
zoom_api_secret = "[ZOOM_API_SECRET]"
zoom_account_id = "[ZOOM_ACCOUNT_ID]"
zoom_client_id = "[ZOOM_CLIENT_ID]"
zoom_client_secret = "[ZOOM_CLIENT_SECRET]"
timeout_minutes = 3
}
Expand All @@ -146,9 +147,11 @@ output "user1" {

## Argument Reference

* `zoom_api_key`(Required, string) - The Zoom API Key. This may also be set via the `"ZOOM_API_KEY"` environment
* `zoom_account_id`(Required, string) - The Zoom Account ID. This may also be set via the `"ZOOM_ACCOUNT_ID"` environment
variable.
* `zoom_api_secret`(Required, string) - The Zoom API Secret. This may also be set via the `"ZOOM_API_SECRET"`
* `zoom_client_id`(Required, string) - The Zoom Client ID. This may also be set via the `"ZOOM_CLIENT_ID"`
environment variable.
* `zoom_client_secret`(Required, string) - The Zoom Client secret. This may also be set via the `"ZOOM_CLIENT_SECRET"`
environment variable.
* `timeout_minutes` (Optional, int) - The duration for which retries to be performed when an API request fails with
API Rate limit error. This may also be set via the `"ZOOM_TIMEOUT_MINUTES"` environment variable. Default value is 2.
Expand All @@ -175,18 +178,3 @@ output "user1" {
* `pronouns`(Optional, string) - User's pronouns.
* `pronouns_option`(Optional, int) - User's display pronouns setting.
* `role_name`(Computed, string) - Current role of the user i.e., (Admin,Member).















48 changes: 46 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
)

Expand Down Expand Up @@ -52,9 +53,13 @@ type Client struct {
httpClient *http.Client
}

func NewClient(token string, timeoutMinutes int) *Client {
type AuthInfo struct {
AccessToken string `json:"access_token,omitempty"`
}

func NewClient(authToken string, timeoutMinutes int) *Client {
return &Client{
authToken: token,
authToken: authToken,
TimeoutMinutes: timeoutMinutes,
httpClient: &http.Client{},
}
Expand Down Expand Up @@ -140,6 +145,45 @@ func (c *Client) ChangeEmail(oldEmail, newEmail string) error {
return nil
}

func (c *Client) GenerateToken(accountId, clientId, clientSecret string) error {
data := url.Values{}
data.Set("grant_type", "account_credentials")
data.Set("account_id", accountId)

req, err := http.NewRequest(http.MethodPost, "https://zoom.us/oauth/token", strings.NewReader(data.Encode()))
if err != nil {
return err
}

req.SetBasicAuth(clientId, clientSecret)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

resp, err := c.httpClient.Do(req)
if err != nil {
log.Println("[ERROR]: ", err)
return err
}

respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("[ERROR]: ", err)
return err
}

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf(string(respBody) + fmt.Sprintf(", StatusCode: %v", resp.StatusCode))
}

info := &AuthInfo{}
err = json.Unmarshal(respBody, &info)
if err != nil {
return err
}

c.authToken = info.AccessToken
return nil
}

func (c *Client) httpRequest(method string, body *strings.Reader, path string) ([]byte, error) {
req, err := http.NewRequest(method, fmt.Sprintf("https://api.zoom.us/v2/users"+path), body)
if err != nil {
Expand Down
29 changes: 20 additions & 9 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/stretchr/testify/assert"
"log"
"os"
"terraform-provider-zoom/token"
"testing"
)

Expand Down Expand Up @@ -41,8 +40,11 @@ func TestClient_GetUser(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.testName, func(t *testing.T) {
apiToken := token.GenerateToken(os.Getenv("ZOOM_API_SECRET"), os.Getenv(os.Getenv("ZOOM_API_KEY")))
client := NewClient(apiToken, 2)
client := NewClient("", 2)
accountId := os.Getenv("ZOOM_ACCOUNT_ID")
clientId := os.Getenv("ZOOM_CLIENT_ID")
clientSecret := os.Getenv("ZOOM_CLIENT_SECRET")
client.GenerateToken(accountId, clientId, clientSecret)
user, err := client.GetUser(tc.email)
if tc.expectErr {
assert.Error(t, err)
Expand Down Expand Up @@ -95,8 +97,11 @@ func TestClient_NewItem(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.testName, func(t *testing.T) {
apiToken := token.GenerateToken(os.Getenv("ZOOM_API_SECRET"), os.Getenv(os.Getenv("ZOOM_API_KEY")))
client := NewClient(apiToken, 2)
client := NewClient("", 2)
accountId := os.Getenv("ZOOM_ACCOUNT_ID")
clientId := os.Getenv("ZOOM_CLIENT_ID")
clientSecret := os.Getenv("ZOOM_CLIENT_SECRET")
client.GenerateToken(accountId, clientId, clientSecret)
_, err := client.NewUser(tc.user)
if tc.expectErr {
assert.Error(t, err)
Expand Down Expand Up @@ -149,8 +154,11 @@ func TestClient_UpdateUser(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.testName, func(t *testing.T) {
apiToken := token.GenerateToken(os.Getenv("ZOOM_API_SECRET"), os.Getenv(os.Getenv("ZOOM_API_KEY")))
client := NewClient(apiToken, 2)
client := NewClient("", 2)
accountId := os.Getenv("ZOOM_ACCOUNT_ID")
clientId := os.Getenv("ZOOM_CLIENT_ID")
clientSecret := os.Getenv("ZOOM_CLIENT_SECRET")
client.GenerateToken(accountId, clientId, clientSecret)
err := client.UpdateUser(tc.user.Email, tc.user)
if tc.expectErr {
assert.Error(t, err)
Expand All @@ -177,8 +185,11 @@ func TestClient_DeleteUser(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.testName, func(t *testing.T) {
apiToken := token.GenerateToken(os.Getenv("ZOOM_API_SECRET"), os.Getenv(os.Getenv("ZOOM_API_KEY")))
client := NewClient(apiToken, 2)
client := NewClient("", 2)
accountId := os.Getenv("ZOOM_ACCOUNT_ID")
clientId := os.Getenv("ZOOM_CLIENT_ID")
clientSecret := os.Getenv("ZOOM_CLIENT_SECRET")
client.GenerateToken(accountId, clientId, clientSecret)
err := client.DeleteUser(tc.email, "pending")
log.Println(err)
if tc.expectErr {
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module terraform-provider-zoom
go 1.16

require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1
github.com/stretchr/testify v1.7.0
)
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
Expand Down
19 changes: 3 additions & 16 deletions token/token.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
package token

import (
"github.com/dgrijalva/jwt-go"
"time"
)
import "terraform-provider-zoom/client"

func GenerateToken(apiSecret, apiKey string) string {
var jwtKey = []byte(apiSecret)
expirationTime := time.Now().Add(20 * time.Minute)
claims := &jwt.StandardClaims{
Audience: " ",
Issuer: apiKey,
ExpiresAt: expirationTime.Unix(),
IssuedAt: time.Now().Unix(),
}
tokenJwt := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, _ := tokenJwt.SignedString(jwtKey)
return token
func GenerateToken(c *client.Client, accountId, clientId, clientSecret string) error {
return c.GenerateToken(accountId, clientId, clientSecret)
}
43 changes: 29 additions & 14 deletions zoom/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@ import (
func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"zoom_api_secret": &schema.Schema{
"zoom_account_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("ZOOM_API_SECRET", ""),
DefaultFunc: schema.EnvDefaultFunc("ZOOM_ACCOUNT_ID", ""),
},
"zoom_api_key": &schema.Schema{
"zoom_client_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("ZOOM_API_KEY", ""),
DefaultFunc: schema.EnvDefaultFunc("ZOOM_CLIENT_ID", ""),
},
"zoom_client_secret": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("ZOOM_CLIENT_SECRET", ""),
},
"zoom_timeout_minutes": &schema.Schema{
Type: schema.TypeInt,
Expand All @@ -36,18 +41,28 @@ func Provider() *schema.Provider {
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
var api_secret string
if v, ok := d.GetOk("zoom_api_secret"); ok {
api_secret = v.(string)
var accountId string
if v, ok := d.GetOk("zoom_client_id"); ok {
accountId = v.(string)
}
var api_key string
if v, ok := d.GetOk("zoom_api_key"); ok {
api_key = v.(string)

var clientId string
if v, ok := d.GetOk("zoom_client_id"); ok {
clientId = v.(string)
}
var timeout_minutes int

var clientSecret string
if v, ok := d.GetOk("zoom_client_secret"); ok {
clientSecret = v.(string)
}

var timeoutMinutes int
if v, ok := d.GetOk("zoom_timeout_minutes"); ok {
timeout_minutes = v.(int)
timeoutMinutes = v.(int)
}
apiToken := token.GenerateToken(api_secret, api_key)
return client.NewClient(apiToken, timeout_minutes), nil

c := client.NewClient("", timeoutMinutes)
err := token.GenerateToken(c, accountId, clientId, clientSecret)

return c, err
}

0 comments on commit ee4c801

Please sign in to comment.