diff --git a/Gemfile b/Gemfile index f0bb897..2482479 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ source "http://rubygems.org" -# Specify your gem's dependencies in cookie-extractor.gemspec +# Specify your gem's dependencies in cookie_extractor.gemspec gemspec diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..23dbbfc --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,28 @@ +PATH + remote: . + specs: + cookie_extractor (0.0.1) + sqlite3-ruby + +GEM + remote: http://rubygems.org/ + specs: + diff-lcs (1.1.3) + rspec (2.8.0) + rspec-core (~> 2.8.0) + rspec-expectations (~> 2.8.0) + rspec-mocks (~> 2.8.0) + rspec-core (2.8.0) + rspec-expectations (2.8.0) + diff-lcs (~> 1.1.2) + rspec-mocks (2.8.0) + sqlite3 (1.3.5) + sqlite3-ruby (1.3.3) + sqlite3 (>= 1.3.3) + +PLATFORMS + ruby + +DEPENDENCIES + cookie_extractor! + rspec diff --git a/bin/cookie-extractor b/bin/cookie-extractor new file mode 100755 index 0000000..b689dd5 --- /dev/null +++ b/bin/cookie-extractor @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "cookie_extractor")) + +Main do + # TODO: detect firefox or chrome input file and/or locate it automatically + filename = ARGV.first + if filename + puts CookieExtractor::FirefoxCookieExtractor.new(filename).extract.join("\n") + else + puts "Usage: cookie-extractor /path/to/cookies.sqlite" + end +end diff --git a/cookie-extractor.gemspec b/cookie_extractor.gemspec similarity index 87% rename from cookie-extractor.gemspec rename to cookie_extractor.gemspec index 1222af2..7ea8ee4 100644 --- a/cookie-extractor.gemspec +++ b/cookie_extractor.gemspec @@ -1,9 +1,9 @@ # -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) -require "cookie-extractor/version" +require "cookie_extractor/version" Gem::Specification.new do |s| - s.name = "cookie-extractor" + s.name = "cookie_extractor" s.version = CookieExtractor::VERSION s.authors = ["Jeff Dallien"] s.email = ["jeff@dallien.net"] @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.summary = %q{Create cookies.txt from Firefox or Chrome cookies} s.description = %q{Extract cookies from Firefox or Chrome sqlite databases into a wget-compatible cookies.txt file.} - s.rubyforge_project = "cookie-extractor" + s.rubyforge_project = "cookie_extractor" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") diff --git a/lib/cookie-extractor.rb b/lib/cookie-extractor.rb deleted file mode 100644 index 4a38a64..0000000 --- a/lib/cookie-extractor.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "cookie-extractor/version" - -module Cookie - module Extractor - # Your code goes here... - end -end diff --git a/lib/cookie_extractor.rb b/lib/cookie_extractor.rb new file mode 100644 index 0000000..20f68f4 --- /dev/null +++ b/lib/cookie_extractor.rb @@ -0,0 +1,5 @@ +require "cookie_extractor/version" +require "cookie_extractor/firefox_cookie_extractor" + +module CookieExtractor +end diff --git a/lib/cookie_extractor/firefox_cookie_extractor.rb b/lib/cookie_extractor/firefox_cookie_extractor.rb new file mode 100644 index 0000000..f7f32c1 --- /dev/null +++ b/lib/cookie_extractor/firefox_cookie_extractor.rb @@ -0,0 +1,42 @@ +require 'sqlite3' + +module CookieExtractor + class FirefoxCookieExtractor + + def initialize(cookie_file) + @cookie_file = cookie_file + end + + def extract + db = SQLite3::Database.new @cookie_file + db.results_as_hash = true + @result = [] + db.execute("SELECT * FROM moz_cookies") do |row| + @result << [ row['host'], + true_false_word(is_domain_wide(row['host'])), + row['path'], + true_false_word(row['isSecure']), + row['expiry'], + row['name'], + row['value'] + ].join("\t") + end + end + + private + + def is_domain_wide(hostname) + hostname[0..0] == "." + end + + def true_false_word(value) + if value == "1" || value == 1 || value == true + "TRUE" + elsif value == "0" || value == 0 || value == false + "FALSE" + else + raise "Invalid value passed to true_false_word: #{value.inspect}" + end + end + end +end diff --git a/lib/cookie-extractor/version.rb b/lib/cookie_extractor/version.rb similarity index 100% rename from lib/cookie-extractor/version.rb rename to lib/cookie_extractor/version.rb diff --git a/spec/.firefox_cookie_extractor_spec.rb.swp b/spec/.firefox_cookie_extractor_spec.rb.swp new file mode 100644 index 0000000..b498031 Binary files /dev/null and b/spec/.firefox_cookie_extractor_spec.rb.swp differ diff --git a/spec/cookie_extractor_spec.rb b/spec/cookie_extractor_spec.rb new file mode 100644 index 0000000..a4b5d49 --- /dev/null +++ b/spec/cookie_extractor_spec.rb @@ -0,0 +1,6 @@ +require File.join(File.dirname(__FILE__), "spec_helper") + +describe CookieExtractor do + + +end diff --git a/spec/firefox_cookie_extractor_spec.rb b/spec/firefox_cookie_extractor_spec.rb new file mode 100644 index 0000000..fb86adf --- /dev/null +++ b/spec/firefox_cookie_extractor_spec.rb @@ -0,0 +1,116 @@ +require File.join(File.dirname(__FILE__), "spec_helper") + +describe CookieExtractor::FirefoxCookieExtractor do + before :each do + @fake_cookie_db = double("cookie database", :results_as_hash= => true) + SQLite3::Database.should_receive(:new). + with('filename'). + and_return(@fake_cookie_db) + end + + describe "with a cookie that has a host starting with a dot" do + before :each do + @fake_cookie_db.should_receive(:execute).and_yield( + {'host' => '.dallien.net', + 'path' => '/', + 'isSecure' => '0', + 'expiry' => '1234567890', + 'name' => 'NAME', + 'value' => 'VALUE'}) + @extractor = CookieExtractor::FirefoxCookieExtractor.new('filename') + @result = @extractor.extract + end + + it "should return one cookie string" do + @result.size.should == 1 + end + + it "should put TRUE in the domain wide field" do + cookie_string = @result.first + cookie_string.split("\t")[1].should == "TRUE" + end + + it "should put FALSE in the secure field" do + cookie_string = @result.first + cookie_string.split("\t")[3].should == "FALSE" + end + + it "should build the correct cookie string" do + cookie_string = @result.first + cookie_string.should == + ".dallien.net\tTRUE\t/\tFALSE\t1234567890\tNAME\tVALUE" + end + end + + describe "with a cookie that has a host not starting with a dot" do + before :each do + @fake_cookie_db.should_receive(:execute).and_yield( + { 'host' => 'jeff.dallien.net', + 'path' => '/path', + 'isSecure' => '1', + 'expiry' => '1234567890', + 'name' => 'NAME', + 'value' => 'VALUE'}) + @extractor = CookieExtractor::FirefoxCookieExtractor.new('filename') + @result = @extractor.extract + end + + it "should return one cookie string" do + @result.size.should == 1 + end + + it "should put FALSE in the domain wide field" do + cookie_string = @result.first + cookie_string.split("\t")[1].should == "FALSE" + end + + it "should put TRUE in the secure field" do + cookie_string = @result.first + cookie_string.split("\t")[3].should == "TRUE" + end + + it "should build the correct cookie string" do + cookie_string = @result.first + cookie_string.should == + "jeff.dallien.net\tFALSE\t/path\tTRUE\t1234567890\tNAME\tVALUE" + end + end + + describe "with a cookie that is not marked as secure" do + before :each do + @fake_cookie_db.should_receive(:execute).and_yield( + {'host' => '.dallien.net', + 'path' => '/', + 'isSecure' => '0', + 'expiry' => '1234567890', + 'name' => 'NAME', + 'value' => 'VALUE'}) + @extractor = CookieExtractor::FirefoxCookieExtractor.new('filename') + @result = @extractor.extract + end + + it "should put FALSE in the secure field" do + cookie_string = @result.first + cookie_string.split("\t")[3].should == "FALSE" + end + end + + describe "with a cookie that is marked as secure" do + before :each do + @fake_cookie_db.should_receive(:execute).and_yield( + {'host' => '.dallien.net', + 'path' => '/', + 'isSecure' => '1', + 'expiry' => '1234567890', + 'name' => 'NAME', + 'value' => 'VALUE'}) + @extractor = CookieExtractor::FirefoxCookieExtractor.new('filename') + @result = @extractor.extract + end + + it "should put TRUE in the secure field" do + cookie_string = @result.first + cookie_string.split("\t")[3].should == "TRUE" + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..dfe6fdc --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,2 @@ +require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "cookie_extractor")) +