Comments (9)
I am leaning towards option 2. I am not sure how 2 would be implemented. Would you move the New-ZoomHeaders to the process block, then create some logic around it in New-ZoomHeaders? Something like:
if ((get-date(Parse-JWTToken -token (New-ZoomApiToken -ApiKey 123 -ApiSecret 456)).exp) -lt (get-date)) {New-ZoomHeaders}
Potentially a fourth option, exposing the -ValidForSeconds parameter to all public functions then passing it to New-ZoomHeaders which will pass it to New-ZoomToken. Edit: Looks like you have suggested exactly this before.
Thank you for taking the time to explain the problem and some solutions. No problems with the English, it's actually near perfect. It is easier to understand than most native speakers.
from pszoom.
I replaced Invoke-RestMethod with Invoke-ZoomRestMethod across all of the \Public\ functions. You can implement New-ZoomHeaders within Invoke-ZoomRestMethod. This should greatly reduce the number of lines of code. In addition, you will have to pass the ApiKey and ApiSecret to Invoke-ZoomRestMethod in each \Public\ function.
You would also have to remove New-ZoomHeaders from the Begin blocks, as well as remove the -Headers parameter from Invoke-ZoomRestMethod calls.
Old:
$Headers = New-ZoomHeaders -ApiKey $ApiKey -ApiSecret $ApiSecret
Invoke-ZoomRestMethod -Uri $request.Uri -Headers $headers -Method GET
New:
Invoke-ZoomRestMethod -Uri $request.Uri -Method GET -ApiKey $ApiKey -ApiSecret $ApiSecret
This method will be pretty neat, as once it is fully implemented, users can call Invoke-ZoomRestMethod fairly easily to call any functions that aren't implemented by the module, by simply adding the uri and method. Invoke-ZoomRestMethod will have to be moved to \Public\Utils.
This is quite the undertaking. Let me know if this makes enough sense or how else I can help.
from pszoom.
An example implementation of Plan2 would look like this code.
In the Process block, it decodes the Header to get the expiration date and compare it with the current time.
Only if the token has expired, it calls New-ZoomHeaders
to update the Header and token.
function Get-ZoomUser {
[CmdletBinding()]
param (
[Parameter(
Mandatory = $True,
Position = 0,
ValueFromPipeline = $True,
ValueFromPipelineByPropertyName = $True
)]
[Alias('email', 'emailaddress', 'id', 'user_id', 'ids', 'userids', 'emails', 'emailaddresses', 'host_id')]
[string[]]$UserId,
[ValidateSet('Facebook', 'Google', 'API', 'Zoom', 'SSO', 0, 1, 99, 100, 101)]
[Alias('login_type')]
[string]$LoginType,
[ValidateNotNullOrEmpty()]
[string]$ApiKey,
[ValidateNotNullOrEmpty()]
[string]$ApiSecret
)
begin {
#Generate Header with JWT (JSON Web Token) using the Api Key/Secret
$headers = New-ZoomHeaders -ApiKey $ApiKey -ApiSecret $ApiSecret
}
process {
foreach ($id in $UserId) {
$request = [System.UriBuilder]"https://api.zoom.us/v2/users/$id"
if ($PSBoundParameters.ContainsKey('LoginType')) {
$LoginType = switch ($LoginType) {
'Facebook' { 0 }
'Google' { 1 }
'API' { 99 }
'Zoom' { 100 }
'SSO' { 101 }
Default { $LoginType }
}
$query = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
$query.Add('login_type', $LoginType)
$Request.Query = $query.ToString()
}
# Update the token if it has expired.
$CurrentUnixTime = ((Get-Date) - (Get-Date '1970/1/1 0:0:0 GMT')).TotalSeconds
$TokenPayload = ($headers.authorization -split '\.')[1]
$TokenExpireTime = [int]((ConvertFrom-Json ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($TokenPayload + '=' * (4 - $TokenPayload.Length % 4))))).exp)
if ($CurrentUnixTime -ge $TokenExpireTime) {
$Headers = New-ZoomHeaders -ApiKey $ApiKey -ApiSecret $ApiSecret
}
$response = Invoke-ZoomRestMethod -Uri $request.Uri -Headers $headers -Method GET
Write-Output $response
}
}
}
from pszoom.
Your plan to change it to create a Header in the Invoke-ZoomRestMethod looks practically the same as implementing my plan 1.
I think it's an attractive plan because it keeps the code simple.
Compared to my plan 2, I think there is a little more processing overhead due to the higher number of token generation. However, in my test, the processing time was about 1 second for 1000 runs, so it may not be a problem.
Do we go ahead with this plan?
from pszoom.
What do you think about having the token expiry logic put into Invoke-RestMethod? You could use $script:headers (I think) to update the token if it has expired. I would like to reduce the lines of code if possible, provided there's no increased overhead (adding 4 lines of code in 80+ files vs in one file).
from pszoom.
Good idea, but the update by $script:Headers
probably won't work. (I haven't tested it)
To update the caller's variables, you need to pass a variable by reference
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_ref
Here is a simple implementation example. I have omitted all the parts that are not necessary for the example, but it is code that works.
Note that $Headers is preceded by a [ref]
modifier.
function Invoke-ZoomRestMethod {
[CmdletBinding(DefaultParameterSetName = 'Default')]
param (
$Method,
[uri]$Uri,
[ref]$Headers
)
# Update the token if it has expired.
$CurrentUnixTime = ((Get-Date) - (Get-Date '1970/1/1 0:0:0 GMT')).TotalSeconds
$TokenPayload = ($Headers.Value.authorization -split '\.')[1]
$TokenExpireTime = [int]((ConvertFrom-Json ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($TokenPayload + '=' * (4 - $TokenPayload.Length % 4))))).exp)
if ($CurrentUnixTime -ge $TokenExpireTime) {
$Headers.Value = New-ZoomHeaders -ApiKey $ApiKey -ApiSecret $ApiSecret
}
$params = @{
Method = $Method
Uri = $Uri
Headers = $Headers.Value
}
try {
$response = Invoke-RestMethod @params
}
catch {
#---- (ellipsis) ----
}
Write-Output $response
}
# ---------------------------------------------------------------- #
function Get-ZoomUser {
[CmdletBinding()]
param (
[string[]]$UserId,
[string]$ApiKey,
[string]$ApiSecret
)
begin {
#Generate Header with JWT (JSON Web Token) using the Api Key/Secret
$headers = New-ZoomHeaders -ApiKey $ApiKey -ApiSecret $ApiSecret
}
process {
foreach ($id in $UserId) {
$request = [System.UriBuilder]"https://api.zoom.us/v2/users/$id"
$response = Invoke-ZoomRestMethod -Uri $request.Uri -Headers ([ref]$Headers) -Method GET
Write-Output $response
}
}
}
from pszoom.
I did not know about [ref]. Good stuff.
If you agree with the implementation you have described most recently, then let's proceed with modifying invoke-zoomresponse to include the expiry logic and updating of headers.
from pszoom.
Okay, I will start to modify the Invoke-ZoomRestMethod
based on the agreement. I will create a PR in a few days, so please wait a bit.
from pszoom.
Good work on this. Your efforts are much appreciated. I should have this shipped out to Powershell Gallery this week.
from pszoom.
Related Issues (20)
- Is there a way to add a manager to a zoom user?
- Error when creating new users: "Invalid URI: The hostname could not be parsed." HOT 3
- Get-ZoomMeetings Error 400 Bad Request HOT 1
- Whatif doesn't prevent action
- 404 Error Removing Users HOT 9
- Get-ZoomUsers -Status All HOT 1
- Where is OAuth on Zoom marketplace HOT 5
- Fix code scanning alert - File 'Connect-PSZoom.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure inf...
- Fix code scanning alert - File 'New-OAuthToken.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure inf... HOT 1
- PSZoom - How to add a manger to a new user?
- Get Sub Account Users HOT 5
- Restart-ZoomRoom 401 error HOT 2
- change the "user type" HOT 1
- Getting Unauthorized error when using Get-ZoomAccountRecordings HOT 1
- zoom call queues HOT 1
- Powershell Gallery is missing new Zoom Phone Functions
- ParticipantVideo parameter not supported by NewMeeting or UpdateMeeting HOT 1
- User accounts not getting created HOT 1
- "Cannot process argument transformation on parameter 'Token'" after updating to 2.0.4.0 HOT 3
- [Query] billing api. Is it possible to query licenses? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pszoom.