From 2c906e3339527f9fadc11ec1867516230e3a1683 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Fri, 18 Jul 2014 12:27:25 -0700 Subject: [PATCH 1/7] Remove existing keys in reqeust header to avoid duplicates when token is refreshed --- lib/ruby-box/session.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ruby-box/session.rb b/lib/ruby-box/session.rb index 8cf96e6..feec6f9 100644 --- a/lib/ruby-box/session.rb +++ b/lib/ruby-box/session.rb @@ -63,12 +63,20 @@ def request(uri, request, raw=false, retries=0) http.ssl_version = :SSLv3 #http.set_debug_output($stdout) + ##Clear the existing request fields to avoid duplicates + if request.key?('Authorization') + request.delete('Authorization') + end + if @access_token request.add_field('Authorization', "Bearer #{@access_token.token}") else request.add_field('Authorization', build_auth_header) end + if request.key?('As-User') + request.delete('As-User') + end request.add_field('As-User', "#{@as_user}") if @as_user From d83b3acfc9b36ac83c1bc45c5c85cbec2d3ecbbd Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Tue, 19 Aug 2014 11:23:29 -0700 Subject: [PATCH 2/7] Added box access code generation --- lib/ruby-box/box_authenticator.rb | 16 ++++++++++++++++ lib/ruby-box/session.rb | 20 ++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100755 lib/ruby-box/box_authenticator.rb diff --git a/lib/ruby-box/box_authenticator.rb b/lib/ruby-box/box_authenticator.rb new file mode 100755 index 0000000..f82ec0a --- /dev/null +++ b/lib/ruby-box/box_authenticator.rb @@ -0,0 +1,16 @@ +require 'sinatra' + +code = nil + +get '/' do + code = params[:code] + if !code.nil? + puts "code=#{code}" + body "Box access code captured. Please return to your program to continue. You can close this window." + end +end + +after do + puts body + Process.kill 'TERM', Process.pid +end diff --git a/lib/ruby-box/session.rb b/lib/ruby-box/session.rb index feec6f9..74621ef 100644 --- a/lib/ruby-box/session.rb +++ b/lib/ruby-box/session.rb @@ -1,4 +1,5 @@ require 'oauth2' +require 'launchy' module RubyBox class Session @@ -15,8 +16,23 @@ def initialize(opts={}, backoff=0.1) if opts[:client_id] @oauth2_client = OAuth2::Client.new(opts[:client_id], opts[:client_secret], OAUTH2_URLS.dup) - @access_token = OAuth2::AccessToken.new(@oauth2_client, opts[:access_token]) if opts[:access_token] - @refresh_token = opts[:refresh_token] + + Launchy.open("https://app.box.com/api/oauth2/authorize?response_type=code&client_id=#{opts[:client_id]}&redirect_uri=http://localhost:4567") + + authTokenCodeOutput = `ruby #{::File.dirname(__FILE__)}/box_authenticator.rb 2> /dev/null` + if authTokenCodeOutput =~ /code=(\w+)/ + authTokenCode = $1 + #puts "Got Auth Code #{authTokenCode}" + else + puts "**ERROR** : Authorization Token Code is not available." + exit + end + @token = get_access_token(authTokenCode) + @access_token = @token.token + @refresh_token = @token.refresh_token + + #@access_token = OAuth2::AccessToken.new(@oauth2_client, opts[:access_token]) if opts[:access_token] + #@refresh_token = opts[:refresh_token] @as_user = opts[:as_user] else # Support legacy API for historical reasons. @api_key = opts[:api_key] From 650faaf66624bc16b70ee057b8456a1da0c06922 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Thu, 21 Aug 2014 13:03:48 -0700 Subject: [PATCH 3/7] Updated refresh token when it gets refreshed --- lib/ruby-box/session.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ruby-box/session.rb b/lib/ruby-box/session.rb index 74621ef..087ec91 100644 --- a/lib/ruby-box/session.rb +++ b/lib/ruby-box/session.rb @@ -28,7 +28,7 @@ def initialize(opts={}, backoff=0.1) exit end @token = get_access_token(authTokenCode) - @access_token = @token.token + @access_token = @token @refresh_token = @token.refresh_token #@access_token = OAuth2::AccessToken.new(@oauth2_client, opts[:access_token]) if opts[:access_token] @@ -54,6 +54,7 @@ def get_access_token(code) def refresh_token(refresh_token) refresh_access_token_obj = OAuth2::AccessToken.new(@oauth2_client, @access_token.token, {'refresh_token' => refresh_token}) @access_token = refresh_access_token_obj.refresh! + @refresh_token = @access_token.refresh_token end def build_auth_header From 0c088b14ad0c22f8ab4280cfb44f34d9f1d1f5d7 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Thu, 21 Aug 2014 13:53:01 -0700 Subject: [PATCH 4/7] Made box based auth token authorization available only for UNIX based OS --- lib/ruby-box/session.rb | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/ruby-box/session.rb b/lib/ruby-box/session.rb index 087ec91..5450649 100644 --- a/lib/ruby-box/session.rb +++ b/lib/ruby-box/session.rb @@ -17,22 +17,24 @@ def initialize(opts={}, backoff=0.1) if opts[:client_id] @oauth2_client = OAuth2::Client.new(opts[:client_id], opts[:client_secret], OAUTH2_URLS.dup) - Launchy.open("https://app.box.com/api/oauth2/authorize?response_type=code&client_id=#{opts[:client_id]}&redirect_uri=http://localhost:4567") - - authTokenCodeOutput = `ruby #{::File.dirname(__FILE__)}/box_authenticator.rb 2> /dev/null` - if authTokenCodeOutput =~ /code=(\w+)/ - authTokenCode = $1 - #puts "Got Auth Code #{authTokenCode}" + ##Redirect to box to generate access key and refresh token only on UNIX based OS + if ::File.exist?('/bin/uname') || ::File.exist?('/usr/bin/uname') + Launchy.open("https://app.box.com/api/oauth2/authorize?response_type=code&client_id=#{opts[:client_id]}&redirect_uri=http://localhost:4567") + authTokenCodeOutput = `ruby #{::File.dirname(__FILE__)}/box_authenticator.rb 2> /dev/null` + if authTokenCodeOutput =~ /code=(\w+)/ + authTokenCode = $1 + #puts "Got Auth Code #{authTokenCode}" + else + puts "**ERROR** : Authorization Token Code is not available." + exit + end + @token = get_access_token(authTokenCode) + @access_token = @token + @refresh_token = @token.refresh_token else - puts "**ERROR** : Authorization Token Code is not available." - exit - end - @token = get_access_token(authTokenCode) - @access_token = @token - @refresh_token = @token.refresh_token - - #@access_token = OAuth2::AccessToken.new(@oauth2_client, opts[:access_token]) if opts[:access_token] - #@refresh_token = opts[:refresh_token] + @access_token = OAuth2::AccessToken.new(@oauth2_client, opts[:access_token]) if opts[:access_token] + @refresh_token = opts[:refresh_token] + end @as_user = opts[:as_user] else # Support legacy API for historical reasons. @api_key = opts[:api_key] From 495e987f83e588b4a1d72b5c0d4a9e173994fc96 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Mon, 25 Aug 2014 10:18:22 -0700 Subject: [PATCH 5/7] Updated README and Gemfile for BOX UI based authentication --- Gemfile | 1 + Gemfile.lock | 8 ++++++++ README.markdown | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 616e438..40ce5b0 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ gem "multipart-post" gem "oauth2" gem "json" gem "addressable" +gem "sinatra" group :development do gem "rspec" diff --git a/Gemfile.lock b/Gemfile.lock index b661fc1..6b08796 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,6 +24,8 @@ GEM multi_json (~> 1.0) rack (~> 1.2) rack (1.4.5) + rack-protection (1.5.3) + rack rake (0.9.2.2) rspec (2.10.0) rspec-core (~> 2.10.0) @@ -33,6 +35,11 @@ GEM rspec-expectations (2.10.0) diff-lcs (~> 1.1.3) rspec-mocks (2.10.1) + sinatra (1.4.5) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) + tilt (1.4.1) webmock (1.8.7) addressable (>= 2.2.7) crack (>= 0.1.7) @@ -48,4 +55,5 @@ DEPENDENCIES multipart-post oauth2 rspec + sinatra webmock diff --git a/README.markdown b/README.markdown index a432952..8a2be58 100644 --- a/README.markdown +++ b/README.markdown @@ -10,7 +10,23 @@ RubyBox provides a simple, chainable, feature-rich client for [Box's 2.0 API](ht Authorization ------------- -RubyBox uses Box's OAuth2 Implementaton, Here are the steps involved in authorizing a client: +RubyBox uses Box's OAuth2 Implementaton. For any UNIX based operating systems (including Linux, MacOS) you can authorize the application through Box's UI and generate the access code and refresh code automatically based on your client ID and client secret. For non UNIX based operating systems, you will have to manually generate the access token and refresh token and find a way to store the refresh token. + +For UNIX based operating systems, here are the steps involved in authorizing a client: + +```ruby +require 'ruby-box' + +session = RubyBox::Session.new({ + client_id: 'your-client-id', + client_secret: 'your-client-secret' +}) +client = RubyBox::Client.new(session) +``` +This should automatically generate the required access token and refresh token for the client to work. You will be required to grant access to the application through Box's UI, every time you run you invoke ruby-box. The access token will be automatically refreshed and there is no need to write any extra lines of code to store the refresh token. + + +For Non-UNIX based operating systems, here are the steps involved in authorizing a client: __1)__ Get the authorization url. From a36b757c2aa0f25ec85c44045d2ed170433e1329 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Mon, 25 Aug 2014 10:43:41 -0700 Subject: [PATCH 6/7] Added launchy to the gemfile list --- Gemfile | 1 + Gemfile.lock | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index 40ce5b0..a4b27f9 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gem "oauth2" gem "json" gem "addressable" gem "sinatra" +gem "launchy" group :development do gem "rspec" diff --git a/Gemfile.lock b/Gemfile.lock index 6b08796..a8e7bbc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,6 +15,8 @@ GEM json (1.7.7) jwt (0.1.5) multi_json (>= 1.0) + launchy (2.1.0) + addressable (~> 2.2.6) multi_json (1.6.0) multipart-post (1.1.5) oauth2 (0.8.0) @@ -52,6 +54,7 @@ DEPENDENCIES bundler jeweler (~> 1.6.4) json + launchy multipart-post oauth2 rspec From 33289af6b11499f68dce3dfba5f5d0809bd8f1d6 Mon Sep 17 00:00:00 2001 From: Sridhar Seetharaman Date: Fri, 17 Oct 2014 10:51:35 -0700 Subject: [PATCH 7/7] Changed SSL version from SSLv3 to TSLv1_2 --- lib/ruby-box/session.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ruby-box/session.rb b/lib/ruby-box/session.rb index 5450649..8f33c49 100644 --- a/lib/ruby-box/session.rb +++ b/lib/ruby-box/session.rb @@ -79,7 +79,8 @@ def request(uri, request, raw=false, retries=0) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true - http.ssl_version = :SSLv3 + http.ssl_version = :TLSv1_2 + #http.ssl_version = :SSLv3 #http.set_debug_output($stdout) ##Clear the existing request fields to avoid duplicates