Skip to content

Instantly share code, notes, and snippets.

@cameronove
Last active August 29, 2015 14:03
Show Gist options
  • Save cameronove/67901ff826d3592d9c4a to your computer and use it in GitHub Desktop.
Save cameronove/67901ff826d3592d9c4a to your computer and use it in GitHub Desktop.
Set of PowerShell functions that allow you to register a Box app on your computer and obtain and user access tokens in order to preform work on Box.com objects.
<#
Author: Cameron Ove
Modified: July 8, 2014
FileName: BoxOAuth2Functions.psm1
Revision: 0.2
Change Log:
Removed reference to RegEditSuit.psm1
No longer need to import the above module to use these functions.
Used PowerShell reg provider to access registry.
(new-item, set-itemproperty, get-itemproperty, test-path)
Purpose:
Allow user to use a Box application via OAuth2 authentication protocol.
Brief:
After creating a 'Application' on http://developer.box.com use the Register-BoxApp to register that app on your computer.
Once the app is registered on computer, the Get-BoxAccessToken will allow you to retrieve your access token or refresh your access token so you can
call different RESTful methods against your Box account.
The Box 'Application' can be registered under different Box Credentials. The Registry can keep a seperate key for each registration (or user Credential).
You can register for multiple box accounts or multiple box Applicatons.
I have an Enterprise account registered to my company email and a developer account registered to my personal email address.
As long as you name the app accordingly you can choose which profile you want the module to run under by changing the environment variable:
BoxRegisteredProfile
i.e.
My Dev account might be registered with the AppName: BoxDevAccount
My Enterprise account my be registered with the AppName: BoxEntAccount
If you register you dev account using the same AppName as you used for your Enterprise account then the Dev account ClientID, Secret, and Tokens will over-write
the Enterprise ClientID, Secret, and Tokens.
I've blogged about how to use some of the functions in this module:
http://blog-powershell.blogspot.com/2014/06/using-powershell-to-manage-boxcom-part.html
http://blog-powershell.blogspot.com/2014/06/using-powershell-to-manage-boxcom-part_30.html
More posts to come...
#>
function Register-BoxAccessToken{
param(
$AppName,
$AccessTokenInfo
)
$RegValueNames = @('access_token','expires_in','restricted_to','refresh_token','token_type')
$RegKey = "HKLM:\SOFTWARE\Box.com\$AppName\BoxAccessToken"
if(-not (Test-Path -Path $RegKey)){
New-Item $RegKey -Force
}
foreach($ValueName in $RegValueNames){
if($ValueName -match 'expires_in'){
Set-ItemProperty -Path $RegKey -Name $ValueName -Value "$((get-date).AddSeconds($AccessTokenInfo.$ValueName))" -Type string
}else{
Set-ItemProperty -Path $RegKey -Name $ValueName -Value $AccessTokenInfo.$ValueName -Type string
}
}
}
function Update-BoxAccessToken{
param(
$AppName,
$RefreshToken
)
$RegKey = Get-ItemProperty -path "HKLM:\SOFTWARE\Box.com\$AppName"
$BoxTokenRequest = @{}
$BoxTokenRequest.grant_type = 'refresh_token'
$BoxTokenRequest.refresh_token = $RefreshToken
$BoxTokenRequest.client_id = $RegKey.ClientID
$BoxTokenRequest.client_secret = $RegKey.ClientSecret
$URI = 'https://www.box.com/api/oauth2/token'
$AccessToken = Invoke-RestMethod -Method Post -Uri $URI -Body $BoxTokenRequest
if($AccessToken){
Register-BoxAccessToken $AppName $AccessToken
return $AccessToken
}else{
return $null
}
}
function Register-BoxApp{
param(
$AppName = $(Throw "AppName is required"),
$ClientID = $(throw "ClientID is Required"),
$ClientSecret = $(throw "ClientSecret is Required"),
$APIKey,
$SecurityKey = 'RegisterBoxAPIPowerShellAppPlusSomeCode'
)
#Register the Box application in workstation's registry
#If registry key does not exist then create it.
$RegKey = "HKLM:\SOFTWARE\Box.com\$AppName"
if(-not (Test-Path -Path $RegKey)){
New-Item $RegKey -Force
}
#Write client_id, client_secret, and API Key provided to Registry when calling function.
Set-ItemProperty -Path $RegKey -Name 'ClientID' -Value $ClientID -Type String
Set-ItemProperty -Path $RegKey -Name 'ClientSecret' -Value $ClientSecret -Type String
Set-ItemProperty -Path $RegKey -Name 'APIKey' -Value $APIKey -Type String
#Write the AppName to a User environment variable so that during future imports the BoxLogicalAccess module will choose the correct Box Profile.
[Environment]::SetEnvironmentVariable('BoxRegisteredProfile',$AppName,'User')
#Go get grant access to Box application via Internet Explorer
$ie = New-Object -ComObject internetexplorer.application
$ie.Visible = $true
$ie.Navigate2("https://app.box.com/api/oauth2/authorize?response_type=code&client_id=$ClientID&state=$SecurityKey")
#Inform user that there is an interactive process in IE that needs to be completed before continuing.
[System.Windows.Forms.MessageBox]::Show("Once you've completed the interactive authorzation process within Internet Explorer, then click 'OK' here to continue." , "Authorizing Box API")
#Grab the authorization code from address bar in IE and close IE
$AuthCode = ($ie.Locationurl -split 'code=')[-1]
$ie.Quit()
#Unlike most of the functionality in the Content API, I can use a standard HashTable to request the access token
#With the Content API I have to convert the hashtables to JSON.
$BoxTokenRequest = @{} #HashTable containing the information needed to obtain an access code.
$BoxTokenRequest.grant_type = 'authorization_code'
$BoxTokenRequest.code = $AuthCode
$BoxTokenRequest.client_id = $ClientID
$BoxTokenRequest.client_secret = $ClientSecret
$URI = 'https://www.box.com/api/oauth2/token'
#RESTful call to Box Content API to retrieve access token.
$AccessToken = Invoke-RestMethod -Method Post -Uri $URI -Body $BoxTokenRequest
#If I get a token then write it to the workstation's registry
if($AccessToken){Register-BoxAccessToken $AppName $AccessToken}
return $AccessToken
}
function Get-BoxAccessToken{
param(
$AppName = $(Throw "Please identify the Box app you want to get a token for.")
)
$RegKey = "HKLM:\software\Box.com\$AppName"
if(-not (Test-Path -Path $RegKey)){
Write-Error -Exception 'Box App Not Registered' -Message "Before you can get a Box Access Token you first need to register the Box app. Please run 'Register-BoxApp' and provide the ClientID, ClientSecret, and the APIKey"
return
}
$RegValueNames = @('access_token','expires_in','restricted_to','refresh_token','token_type')
$BoxAccessTokenInfo = [ordered]@{}
$AccessTokenValues = Get-ItemProperty -Path "$RegKey\BoxAccessToken"
foreach($ValueName in $RegValueNames){
$BoxAccessTokenInfo.$ValueName = $AccessTokenValues.$ValueName
}
$TokenExpirationTime = Get-Date $BoxAccessTokenInfo.expires_in
if((Get-Date) -gt $TokenExpirationTime){
$BoxAccessTokenInfo = Update-BoxAccessToken $AppName $BoxAccessTokenInfo.refresh_token
}
return $BoxAccessTokenInfo
}
Export-ModuleMember -Function Get-BoxAccessToken, Register-BoxApp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment