Coder Social home page Coder Social logo

Comments (9)

JosephMcEvoy avatar JosephMcEvoy commented on July 18, 2024

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.

JosephMcEvoy avatar JosephMcEvoy commented on July 18, 2024

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.

mkht avatar mkht commented on July 18, 2024

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.

mkht avatar mkht commented on July 18, 2024

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.

JosephMcEvoy avatar JosephMcEvoy commented on July 18, 2024

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.

mkht avatar mkht commented on July 18, 2024

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.

JosephMcEvoy avatar JosephMcEvoy commented on July 18, 2024

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.

mkht avatar mkht commented on July 18, 2024

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.

JosephMcEvoy avatar JosephMcEvoy commented on July 18, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.