Bitbucket.v2.psm1

Function Connect-Bitbucket {    
    <#
        .Synopsis
            Logs into Bitbucket as a User or is Authorized by Bitbucket as a Consumer and the Credential are used with the Bitbucket API.
        .DESCRIPTION
            Stores Credential in your current PowerShell session for later use.
        .EXAMPLE
            Connect-Bitbucket -Mode User
        .EXAMPLE
            Connect-Bitbucket -Mode User -Credential $UserCredential
        .EXAMPLE
            Connect-Bitbucket -Mode Consumer
        .EXAMPLE
            Connect-Bitbucket -Mode Consumer -Credential $Credential
        .PARAMETER Mode
            Must be either User or Consumer
            User - Sets Credentials as a Bitbucket User using the User Bitbucket UserID and Password
            Consumer - Sets Credentials as a Consumer using the Consumer Key (ClientID) and Secret
    #>

    
    [CmdLetBinding()]
    param (
                
        [Parameter(mandatory)]
        [ValidateSet("User", "Consumer")]
        [string]$Mode,

        [Parameter()]
        [PSCredential]$Credential
    
    )
    
    begin {

        if ($Credential -and $Mode -eq "User") { $global:bbCredential = $Credential }
        if ($Credential -and $Mode -eq "Consumer") { $global:bbConsumer = $Credential }

        Write-Host "`r`n Getting Bitbucket $Mode Credentials....." -ForegroundColor Yellow

    }

    process {

        if ($Mode -eq "User") {
    
            if( !(Test-Path Variable::global:bbCredential) -or ($global:bbCredential -isnot [PSCredential]) ) {

                $global:bbCredential = Get-Credential -Message "Enter your Bitbucket UserID and Password."
    
            }

        } elseif ($Mode -eq "Consumer") {

            if( !(Test-Path Variable::global:bbConsumer) -or ($global:bbConsumer -isnot [PSCredential]) ) {

                $global:bbConsumer = Get-Credential -Message "Enter your Bitbucket Consumer Key and Secret."
    
            }

        }

    }

}

Function Get-BitbucketAuthCode {

    <#
        .Synopsis
           Gets an OAuth2 Authorization Code for use with the Bitbucket API.
        .DESCRIPTION
           This script uses a web form to acquire an Authorization Code for the specified consumer.
        .EXAMPLE
           Get-BitbucketAuthCode
    #>


    begin {

        # Consumer ClientID if not already done
        Connect-Bitbucket -Mode Consumer  

        Write-Host "`r`n Requesting Authorization Code from Bitbucket....." -ForegroundColor Yellow
    
    }

    process {

        [System.Uri]$uri = "https://bitbucket.org/site/oauth2/authorize?response_type=code" + "&" + "client_id=" + $global:bbConsumer.UserName

        Add-Type -AssemblyName System.Windows.Forms
        Add-Type -AssemblyName System.Web
 
        $form = New-Object -TypeName System.Windows.Forms.Form -Property @{ Width=440; Height=640 }
        $web  = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{ Width=420; Height=600; Url=($uri) }
    
        $docComp  = {
            $Global:uri = $web.Url.AbsoluteUri
            if ($Global:Uri -match "error=[^&]*|code=[^&]*") { $form.Close() }
        }
    
        $web.ScriptErrorsSuppressed = $true
        $web.Add_DocumentCompleted($DocComp)
    
        $form.Controls.Add($web)
        $form.Add_Shown({$form.Activate()})
        $form.ShowDialog() | Out-Null

        $queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)       
    
        $global:authCode = $queryOutput["code"]
    
        if ($global:authCode) {

            Write-Host " Access Code is: " -ForegroundColor Green -NoNewline
            Write-Host $global:authCode -ForegroundColor White
    
        } else {

            throw "Unable to obtain Authorization Code"
    
        }

    }

}

Function Get-Bitbucket {
    
    <#
        .Synopsis
           Obtains either a Consumer Key (ClientID) and Secret or an Access Token to use with the Bitbucket API.
        .DESCRIPTION
            Depending on the Mode, this script either:
                1. Uses the 'password Grant' OAuth2 flow to list all Consumers for a specified Bitbucket User.
                2. uses the 'Authorization Code Grant' OAuth2 flow to acquire an Access Token for the specified consumer.
        .EXAMPLE
           Get-Bitbucket -Mode Key -UserID bloggsj
        .EXAMPLE
           Get-Bitbucket -Mode Key -UserID bloggsj -Credential $UserCreds
        .EXAMPLE
           Get-Bitbucket -Mode Token
        .EXAMPLE
           Get-Bitbucket -Mode Token -Credential $ConsumerCreds
        .PARAMETER UserID
            The Bitbucket User Name used in the Bitbucket URL e.g. https://bitbucket.org/bloggsj
        .PARAMETER Mode
            Must be either Key or Token.
            Key - Obtains all Consumer Keys (ClientID) and Secrets for a Bitbucket User
            Token - Obtains an Access Token for a Consumer
    #>


    [CmdLetBinding()]
    Param (

        [Parameter()]
        [string]$UserID,

        [Parameter(mandatory)]
        [ValidateSet("Key", "Token")]
        [string]$Mode,

        [Parameter()]
        [PSCredential]$Credential

    )

    begin {
               
        Function ConvertTo-Base64String {

            param (

                [Parameter(mandatory)]
                [PSCredential]$Creds            

            )

            return ( [Convert]::ToBase64String( [Text.Encoding]::ASCII.GetBytes( ( "{0}:{1}" -f $creds.UserName, [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR( $creds.Password ) ) ) ) ) )
    
        }

        Clear-Host

    }

    process {

        if ($Mode -eq "Key") {
  
            Write-Host "`r`n Get Consumer Keys from Bitbucket" -ForegroundColor Cyan

            try {

                Connect-Bitbucket -Mode User -Credential $Credential

                [string]$EndpointUrl = "https://api.bitbucket.org/1.0/users/" + $UserID + "/consumers"
                    
                $base64AuthInfo = ConvertTo-Base64String -Creds $global:bbCredential
                
                Write-Host "`r`n Requesting Consumer Keys from Bitbucket....." -ForegroundColor Yellow
                $output = Invoke-RestMethod -Uri $endpointUrl -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) } -Method Get -ErrorVariable _Err -ErrorAction SilentlyContinue

                $output | % {
                    
                    Write-Host " Consumer:`t" -ForegroundColor Green -NoNewline
                    Write-Host $output.name -ForegroundColor White
                    Write-Host " Key:`t`t" -ForegroundColor Green -NoNewline
                    Write-Host $output.key -ForegroundColor White
                    Write-Host " Secret:`t" -ForegroundColor Green -NoNewline
                    Write-Host $output.secret -ForegroundColor White
                    Write-Host
                }

            }
            catch { Write-Error $_ }

        }

        if ($Mode -eq "Token") {
        
            Write-Host "`r`n Get Access Token from Bitbucket" -ForegroundColor Cyan

            try {
        
                Get-BitbucketAuthCode

                [string]$EndpointUrl = "https://bitbucket.org/site/oauth2/access_token"

                $base64AuthInfo = ConvertTo-Base64String -creds $global:bbConsumer

                $requestBody = @{
                    grant_type = 'authorization_code'
                    code = $global:authCode
                }

                Write-Host "`r`n Requesting Access Token from Bitbucket....." -ForegroundColor Yellow
                $output = Invoke-RestMethod -Uri $EndpointUrl -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) } -Method Post -Body $requestBody -ErrorVariable _Err -ErrorAction SilentlyContinue

                Write-Host " Access Token is: " -ForegroundColor Green -NoNewline
                Write-Host $output.access_token -ForegroundColor White
                Write-Host
                
            }
            catch { Write-Error $_ }

        }

    }
        
}