From 7f48e6a25879b6e9a654df783250f97779c0386b Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 10:27:59 -0400 Subject: [PATCH 01/13] New AuthTokenFile class for managing the auth_token file --- lib/auth_token_file.rb | 13 +++++++++++++ spec/auth_token_file_spec.rb | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 lib/auth_token_file.rb create mode 100644 spec/auth_token_file_spec.rb diff --git a/lib/auth_token_file.rb b/lib/auth_token_file.rb new file mode 100644 index 0000000..b7f7194 --- /dev/null +++ b/lib/auth_token_file.rb @@ -0,0 +1,13 @@ +module Gist + class AuthTokenFile + + def filename + if ENV.key?(URL_ENV_NAME) + File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/[^a-z.]/, '')}" + else + File.expand_path "~/.gist" + end + end + + end +end diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb new file mode 100644 index 0000000..8503c10 --- /dev/null +++ b/spec/auth_token_file_spec.rb @@ -0,0 +1,32 @@ +require_relative '../lib/auth_token_file' + +describe Gist::AuthTokenFile do + before(:context) { Gist::URL_ENV_NAME = "GITHUB_URL" } + + context "without custom GITHUB_URL" do + + describe "#filename" do + let(:filename) { File.expand_path "~/.gist" } + + it "is stored in $HOME" do + subject.filename.should eq filename + end + end + + end + + context "with custom GITHUB_URL" do + let(:github_url) { "gh.custom.org" } + before { ENV[Gist::URL_ENV_NAME] = github_url } + + describe "#filename" do + let(:filename) { File.expand_path "~/.gist" } + + it "is stored in $HOME" do + subject.filename.should eq "#{filename}.#{github_url}" + end + end + + end + +end From 8ea0372521733bbd5b3d2260b9a7109dec8bb1a3 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 14:10:08 -0400 Subject: [PATCH 02/13] use a different ENV var for testing --- spec/auth_token_file_spec.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 8503c10..67e3b86 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -1,10 +1,11 @@ require_relative '../lib/auth_token_file' describe Gist::AuthTokenFile do - before(:context) { Gist::URL_ENV_NAME = "GITHUB_URL" } + before(:each) do + stub_const("Gist::URL_ENV_NAME", "STUBBED_GITHUB_URL") + end context "without custom GITHUB_URL" do - describe "#filename" do let(:filename) { File.expand_path "~/.gist" } @@ -17,7 +18,9 @@ context "with custom GITHUB_URL" do let(:github_url) { "gh.custom.org" } - before { ENV[Gist::URL_ENV_NAME] = github_url } + before do + ENV[Gist::URL_ENV_NAME] = github_url + end describe "#filename" do let(:filename) { File.expand_path "~/.gist" } From 155f17f16a8bc378245faecfcee7489fef1d9568 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 10:40:19 -0400 Subject: [PATCH 03/13] use AuthTokenFile for filename --- lib/gist.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/gist.rb b/lib/gist.rb index bc30d06..82d38f7 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -1,6 +1,7 @@ require 'net/https' require 'cgi' require 'uri' +require_relative 'auth_token_file' begin require 'json' @@ -44,7 +45,7 @@ class ClipboardError < RuntimeError; include Error end # # @return [String] string value of access token or `nil`, if not found def auth_token - @token ||= File.read(auth_token_file).chomp rescue nil + @token ||= File.read(auth_token_file.filename).chomp rescue nil end # Upload a gist to https://gist.github.com @@ -258,7 +259,7 @@ def login!(credentials={}) end if Net::HTTPCreated === response - File.open(auth_token_file, 'w', 0600) do |f| + File.open(auth_token_file.filename, 'w', 0600) do |f| f.write JSON.parse(response.body)['token'] end puts "Success! #{ENV[URL_ENV_NAME] || "https://github.com/"}settings/applications" @@ -442,11 +443,7 @@ def api_url end def auth_token_file - if ENV.key?(URL_ENV_NAME) - File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/[^a-z.]/, '')}" - else - File.expand_path "~/.gist" - end + @auth_token_file ||= AuthTokenFile.new end def legacy_private_gister? From 0fe1c057030e785475418135e57b336978efbac3 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 14:50:30 -0400 Subject: [PATCH 04/13] refactor specs --- spec/auth_token_file_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 67e3b86..7ada2fa 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -6,11 +6,11 @@ end context "without custom GITHUB_URL" do - describe "#filename" do - let(:filename) { File.expand_path "~/.gist" } + let(:expected_filename) { File.expand_path "~/.gist" } + describe "#filename" do it "is stored in $HOME" do - subject.filename.should eq filename + subject.filename.should eq expected_filename end end @@ -18,15 +18,15 @@ context "with custom GITHUB_URL" do let(:github_url) { "gh.custom.org" } + let(:expected_filename) { File.expand_path "~/.gist.#{github_url}" } + before do ENV[Gist::URL_ENV_NAME] = github_url end describe "#filename" do - let(:filename) { File.expand_path "~/.gist" } - it "is stored in $HOME" do - subject.filename.should eq "#{filename}.#{github_url}" + subject.filename.should eq expected_filename end end From 1cbe509412be42e3effad329cd60e7cd8bc58cc2 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:02:06 -0400 Subject: [PATCH 05/13] add AuthTokenFile#read --- lib/auth_token_file.rb | 4 ++++ spec/auth_token_file_spec.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/auth_token_file.rb b/lib/auth_token_file.rb index b7f7194..46d8f70 100644 --- a/lib/auth_token_file.rb +++ b/lib/auth_token_file.rb @@ -9,5 +9,9 @@ def filename end end + def read + File.read(filename).chomp + end + end end diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 7ada2fa..2598dad 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -14,6 +14,19 @@ end end + describe "#read" do + let(:token) { "auth_token" } + + it "reads file contents" do + File.should_receive(:read).with(expected_filename).and_return(token) + subject.read.should eq token + end + + it "chomps file contents" do + File.should_receive(:read).with(expected_filename).and_return(token + "\n") + subject.read.should eq token + end + end end context "with custom GITHUB_URL" do From 98103a5485be4c3c1ae18a3326ab6a814b3ea71b Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:13:43 -0400 Subject: [PATCH 06/13] refactor specs --- spec/auth_token_file_spec.rb | 47 +++++++++++++++++------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 2598dad..a50c6b0 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -5,44 +5,41 @@ stub_const("Gist::URL_ENV_NAME", "STUBBED_GITHUB_URL") end - context "without custom GITHUB_URL" do - let(:expected_filename) { File.expand_path "~/.gist" } + describe "#filename" do + let(:filename) { double() } - describe "#filename" do - it "is stored in $HOME" do - subject.filename.should eq expected_filename + context "with default GITHUB_URL" do + it "is ~/.gist" do + File.should_receive(:expand_path).with("~/.gist").and_return(filename) + subject.filename.should be filename end end - describe "#read" do - let(:token) { "auth_token" } - - it "reads file contents" do - File.should_receive(:read).with(expected_filename).and_return(token) - subject.read.should eq token + context "with custom GITHUB_URL" do + before do + ENV[Gist::URL_ENV_NAME] = github_url end + let(:github_url) { "gh.custom.org" } - it "chomps file contents" do - File.should_receive(:read).with(expected_filename).and_return(token + "\n") - subject.read.should eq token + it "is ~/.gist.{custom_github_url}" do + File.should_receive(:expand_path).with("~/.gist.#{github_url}").and_return(filename) + subject.filename.should be filename end end + end - context "with custom GITHUB_URL" do - let(:github_url) { "gh.custom.org" } - let(:expected_filename) { File.expand_path "~/.gist.#{github_url}" } + describe "#read" do + let(:token) { "auth_token" } - before do - ENV[Gist::URL_ENV_NAME] = github_url + it "reads file contents" do + File.should_receive(:read).and_return(token) + subject.read.should eq token end - describe "#filename" do - it "is stored in $HOME" do - subject.filename.should eq expected_filename - end + it "chomps file contents" do + File.should_receive(:read).and_return(token + "\n") + subject.read.should eq token end - end - end From 65e7884cfb5f2ded50aa89c265af5a2bd17a9412 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:29:06 -0400 Subject: [PATCH 07/13] update gist to use AuthTokenFile#read --- lib/gist.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gist.rb b/lib/gist.rb index 82d38f7..cf56da1 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -45,7 +45,7 @@ class ClipboardError < RuntimeError; include Error end # # @return [String] string value of access token or `nil`, if not found def auth_token - @token ||= File.read(auth_token_file.filename).chomp rescue nil + @token ||= auth_token_file.read rescue nil end # Upload a gist to https://gist.github.com From 08865e30d7b90274f3802cf2bebfdd7f3e3ed9c8 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:29:21 -0400 Subject: [PATCH 08/13] add AuthTokenFile#write --- lib/auth_token_file.rb | 5 +++++ spec/auth_token_file_spec.rb | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/auth_token_file.rb b/lib/auth_token_file.rb index 46d8f70..a138166 100644 --- a/lib/auth_token_file.rb +++ b/lib/auth_token_file.rb @@ -13,5 +13,10 @@ def read File.read(filename).chomp end + def write(token) + File.write filename, token, + :mode => 'w', + :perm => 0600 + end end end diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index a50c6b0..33a5ec0 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -42,4 +42,18 @@ subject.read.should eq token end end + + describe "#write" do + let(:token) { double() } + let(:filename) { double() } + + before do + subject.stub(:filename) { filename } + end + + it "writes token to file" do + File.should_receive(:write).with(filename, token, :mode => 'w', :perm => 0600) + subject.write(token) + end + end end From 6ffba6a484f55a5f499d753a2f7766dd80d7fe23 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:30:29 -0400 Subject: [PATCH 09/13] update gist to use AuthTokenFile#write --- lib/gist.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/gist.rb b/lib/gist.rb index cf56da1..e26e555 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -259,9 +259,7 @@ def login!(credentials={}) end if Net::HTTPCreated === response - File.open(auth_token_file.filename, 'w', 0600) do |f| - f.write JSON.parse(response.body)['token'] - end + auth_token_file.write JSON.parse(response.body)['token'] puts "Success! #{ENV[URL_ENV_NAME] || "https://github.com/"}settings/applications" return elsif Net::HTTPUnauthorized === response From 59bf572784814148235be7dd63bd2c6fc90e5a67 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Fri, 31 Oct 2014 15:43:04 -0400 Subject: [PATCH 10/13] AuthTokenFile needn't be a class (no state). just functions --- lib/auth_token_file.rb | 9 +++++---- lib/gist.rb | 8 ++------ spec/auth_token_file_spec.rb | 8 +++++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/auth_token_file.rb b/lib/auth_token_file.rb index a138166..92930c5 100644 --- a/lib/auth_token_file.rb +++ b/lib/auth_token_file.rb @@ -1,7 +1,7 @@ module Gist - class AuthTokenFile + module AuthTokenFile - def filename + def self.filename if ENV.key?(URL_ENV_NAME) File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/[^a-z.]/, '')}" else @@ -9,14 +9,15 @@ def filename end end - def read + def self.read File.read(filename).chomp end - def write(token) + def self.write(token) File.write filename, token, :mode => 'w', :perm => 0600 end + end end diff --git a/lib/gist.rb b/lib/gist.rb index e26e555..d9f91c9 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -45,7 +45,7 @@ class ClipboardError < RuntimeError; include Error end # # @return [String] string value of access token or `nil`, if not found def auth_token - @token ||= auth_token_file.read rescue nil + @token ||= AuthTokenFile.read rescue nil end # Upload a gist to https://gist.github.com @@ -259,7 +259,7 @@ def login!(credentials={}) end if Net::HTTPCreated === response - auth_token_file.write JSON.parse(response.body)['token'] + AuthTokenFile.write JSON.parse(response.body)['token'] puts "Success! #{ENV[URL_ENV_NAME] || "https://github.com/"}settings/applications" return elsif Net::HTTPUnauthorized === response @@ -440,10 +440,6 @@ def api_url ENV.key?(URL_ENV_NAME) ? URI(ENV[URL_ENV_NAME]) : GITHUB_API_URL end - def auth_token_file - @auth_token_file ||= AuthTokenFile.new - end - def legacy_private_gister? return unless which('git') `git config --global gist.private` =~ /\Ayes|1|true|on\z/i diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 33a5ec0..096b80f 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -1,11 +1,13 @@ require_relative '../lib/auth_token_file' describe Gist::AuthTokenFile do + subject { Gist::AuthTokenFile } + before(:each) do stub_const("Gist::URL_ENV_NAME", "STUBBED_GITHUB_URL") end - describe "#filename" do + describe "::filename" do let(:filename) { double() } context "with default GITHUB_URL" do @@ -29,7 +31,7 @@ end - describe "#read" do + describe "::read" do let(:token) { "auth_token" } it "reads file contents" do @@ -43,7 +45,7 @@ end end - describe "#write" do + describe "::write" do let(:token) { double() } let(:filename) { double() } From 8fc7c7a3bafeff28e1f67523ba256ebf8f3db74d Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Sun, 2 Nov 2014 21:29:35 -0500 Subject: [PATCH 11/13] no require-relative --- lib/gist.rb | 2 +- lib/{ => gist}/auth_token_file.rb | 0 spec/auth_token_file_spec.rb | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename lib/{ => gist}/auth_token_file.rb (100%) diff --git a/lib/gist.rb b/lib/gist.rb index d9f91c9..a74b919 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -1,7 +1,7 @@ require 'net/https' require 'cgi' require 'uri' -require_relative 'auth_token_file' +require 'gist/auth_token_file' begin require 'json' diff --git a/lib/auth_token_file.rb b/lib/gist/auth_token_file.rb similarity index 100% rename from lib/auth_token_file.rb rename to lib/gist/auth_token_file.rb diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 096b80f..1319585 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -1,4 +1,4 @@ -require_relative '../lib/auth_token_file' +require 'gist/auth_token_file' describe Gist::AuthTokenFile do subject { Gist::AuthTokenFile } From b435ae37b2eb5e156f6975bd13da4cb280c6d259 Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Sun, 2 Nov 2014 21:44:21 -0500 Subject: [PATCH 12/13] 1.8-compatible IO api --- lib/gist/auth_token_file.rb | 6 +++--- spec/auth_token_file_spec.rb | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/gist/auth_token_file.rb b/lib/gist/auth_token_file.rb index 92930c5..b0e58de 100644 --- a/lib/gist/auth_token_file.rb +++ b/lib/gist/auth_token_file.rb @@ -14,9 +14,9 @@ def self.read end def self.write(token) - File.write filename, token, - :mode => 'w', - :perm => 0600 + File.open(filename, 'w', 0600) do |f| + f.write token + end end end diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 1319585..572721c 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -48,13 +48,15 @@ describe "::write" do let(:token) { double() } let(:filename) { double() } + let(:token_file) { double() } before do subject.stub(:filename) { filename } end it "writes token to file" do - File.should_receive(:write).with(filename, token, :mode => 'w', :perm => 0600) + File.should_receive(:open).with(filename, 'w', 0600).and_yield(token_file) + token_file.should_receive(:write).with(token) subject.write(token) end end From b5b7ae5e422161837a4455134d1e7d7aa329104a Mon Sep 17 00:00:00 2001 From: Jason Karns Date: Mon, 3 Nov 2014 15:30:39 -0500 Subject: [PATCH 13/13] move AuthTokenFile into gist.rb --- lib/gist.rb | 22 +++++++++++++++++++++- lib/gist/auth_token_file.rb | 23 ----------------------- spec/auth_token_file_spec.rb | 2 -- 3 files changed, 21 insertions(+), 26 deletions(-) delete mode 100644 lib/gist/auth_token_file.rb diff --git a/lib/gist.rb b/lib/gist.rb index a74b919..84d3a2c 100644 --- a/lib/gist.rb +++ b/lib/gist.rb @@ -1,7 +1,6 @@ require 'net/https' require 'cgi' require 'uri' -require 'gist/auth_token_file' begin require 'json' @@ -41,6 +40,27 @@ def self.exception(*args) end class ClipboardError < RuntimeError; include Error end + # helper module for authentication token actions + module AuthTokenFile + def self.filename + if ENV.key?(URL_ENV_NAME) + File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/[^a-z.]/, '')}" + else + File.expand_path "~/.gist" + end + end + + def self.read + File.read(filename).chomp + end + + def self.write(token) + File.open(filename, 'w', 0600) do |f| + f.write token + end + end + end + # auth token for authentication # # @return [String] string value of access token or `nil`, if not found diff --git a/lib/gist/auth_token_file.rb b/lib/gist/auth_token_file.rb deleted file mode 100644 index b0e58de..0000000 --- a/lib/gist/auth_token_file.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Gist - module AuthTokenFile - - def self.filename - if ENV.key?(URL_ENV_NAME) - File.expand_path "~/.gist.#{ENV[URL_ENV_NAME].gsub(/[^a-z.]/, '')}" - else - File.expand_path "~/.gist" - end - end - - def self.read - File.read(filename).chomp - end - - def self.write(token) - File.open(filename, 'w', 0600) do |f| - f.write token - end - end - - end -end diff --git a/spec/auth_token_file_spec.rb b/spec/auth_token_file_spec.rb index 572721c..e71e3d8 100644 --- a/spec/auth_token_file_spec.rb +++ b/spec/auth_token_file_spec.rb @@ -1,5 +1,3 @@ -require 'gist/auth_token_file' - describe Gist::AuthTokenFile do subject { Gist::AuthTokenFile }