quickbase 0.0.12 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb7aa9ed00a1e58a91709c83c6071dc3a8d7a533
4
+ data.tar.gz: 8b727513e2f934821254293bec240a16ca25eb9b
5
+ SHA512:
6
+ metadata.gz: 93dbb3372277f563332168f9a34259b895461ce595cd99cebb1939eade4c722f8a40c8326c6457b8b3d804e4bf89bce752651dea4b10e05ddb3e758a989c3409
7
+ data.tar.gz: 35f9785c73be1def7d3902a418351df6f7888ff7378aeaca230d9a818773644f2f3d892bd6d83e050009f65989c333e07684f8db8ed893a4ef328e29ccc80809
@@ -44,13 +44,20 @@ or, in your Gemfile
44
44
  quickbase.api.delete_record(7)
45
45
 
46
46
  == Setting a proxy
47
-
47
+
48
48
  quickbase = Quickbase::Connection.new(:apptoken => "apptoken", :dbid => "dbid", :http_proxy => "http://my.proxy.com:80")
49
49
 
50
50
  the sytem http_proxy, https_proxy and no_proxy environment variable will be respected if you don't explicity pass a proxy
51
51
 
52
52
  == Changes
53
53
 
54
+ 11/11/2016 - version 0.1.0
55
+ - fix security vulnerabilities to xml injections
56
+ - add vcr to tests
57
+ - add MIT license
58
+ - remove deprecated classes
59
+ - fix warnings with gemspec
60
+
54
61
  04/01/2015
55
62
  - Added proxy support
56
63
 
@@ -1,11 +1,11 @@
1
1
  module Quickbase
2
2
  class API
3
3
  attr_accessor :connection
4
-
4
+
5
5
  def initialize(connection)
6
- instance_variable_set "@connection", connection
6
+ @connection = connection
7
7
  end
8
-
8
+
9
9
  # Documentation at http://www.quickbase.com/api-guide/do_query.html
10
10
  def do_query(params)
11
11
  params[:fmt] = 'structured' if params[:fmt].nil? or params[:fmt].empty?
@@ -17,49 +17,44 @@ module Quickbase
17
17
  records = array_of_records.empty? ? response.xpath("//record") : array_of_records
18
18
  return [] if records.empty?
19
19
 
20
- records.map{|record|
20
+ records.map do |record|
21
21
  array_of_fields = record.xpath("f[@type='array']/f")
22
22
  fields = array_of_fields.empty? ? record.xpath("f") : array_of_fields
23
- Hash[fields.to_enum(:each_with_index).collect{|field,index|
23
+ Hash[fields.to_enum(:each_with_index).collect { |field,index|
24
24
  field_val = ""
25
25
  field_val_xpath = field.xpath("__content__").first
26
26
  field_val = field_val_xpath.content unless field_val_xpath.nil?
27
27
  Hash[keys[index],field_val]
28
28
  }.map(&:flatten)]
29
- }
29
+ end
30
30
  end
31
-
31
+
32
32
  def do_query_return_nokogiri_obj(params)
33
33
  #useful method for debugging
34
34
  params[:fmt] = 'structured' if params[:fmt].nil? or params[:fmt].empty?
35
35
  clist = params[:clist].to_s.split(".")
36
36
  friendly = params[:friendly].to_s.split(".")
37
37
  keys = friendly.empty? ? clist : friendly.map(&:to_sym)
38
- response = connection.http.post("API_DoQuery", Quickbase::Helper.hash_to_xml(params))
39
- return response
38
+ connection.http.post("API_DoQuery", Quickbase::Helper.hash_to_xml(params))
40
39
  end
41
-
40
+
42
41
  # Documentation at http://www.quickbase.com/api-guide/add_record.html
43
42
  def add_record(fields)
44
43
  fields = Quickbase::Helper.generate_fields(fields)
45
44
  connection.http.post("API_AddRecord", fields)
46
45
  end
47
-
46
+
48
47
  # Documentation at http://www.quickbase.com/api-guide/edit_record.html
49
48
  def edit_record(rid, fields)
50
49
  tags = Quickbase::Helper.generate_fields(fields)
51
50
  tags << Quickbase::Helper.hash_to_xml({:rid => rid.to_s})
52
51
  connection.http.post("API_EditRecord", tags)
53
52
  end
54
-
53
+
55
54
  # Documentation at http://www.quickbase.com/api-guide/delete_record.html
56
55
  def delete_record(rid)
57
56
  tags = Quickbase::Helper.hash_to_xml({:rid => rid.to_s})
58
57
  connection.http.post("API_DeleteRecord", tags)
59
58
  end
60
59
  end
61
-
62
- class Api < API
63
- puts "Class Api will be deprecated. Please use API instead."
64
- end
65
- end
60
+ end
@@ -1,9 +1,9 @@
1
1
  module Quickbase
2
2
  class Connection
3
3
  class << self
4
- attr_writer :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy
4
+ attr_writer :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy, :usertoken
5
5
  end
6
- attr_reader :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy
6
+ attr_reader :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy, :usertoken
7
7
 
8
8
  def self.expectant_reader(*attributes)
9
9
  attributes.each do |attribute|
@@ -13,24 +13,25 @@ module Quickbase
13
13
  end
14
14
  end
15
15
  end
16
- expectant_reader :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy
16
+ expectant_reader :username, :password, :hours, :apptoken, :dbid, :org, :http_proxy, :usertoken
17
17
 
18
18
  def initialize(options = {})
19
- [:username, :password, :hours, :apptoken, :dbid, :org, :http_proxy].each do |attr|
19
+ [:username, :password, :hours, :apptoken, :dbid, :org, :http_proxy, :usertoken].each do |attr|
20
20
  instance_variable_set "@#{attr}", (options[attr].nil? ? Quickbase::Connection.send(attr) : options[attr])
21
21
  end
22
22
  instance_variable_set "@org", "www" if org.nil?
23
23
  end
24
24
 
25
25
  def instantiate
26
- config = {
27
- :username => username,
28
- :password => password,
29
- :hours => hours,
30
- :apptoken => apptoken,
31
- :dbid => dbid,
32
- :org => org,
33
- :http_proxy => http_proxy
26
+ {
27
+ username: username,
28
+ password: password,
29
+ hours: hours,
30
+ apptoken: apptoken,
31
+ dbid: dbid,
32
+ org: org,
33
+ http_proxy: http_proxy,
34
+ usertoken: usertoken
34
35
  }
35
36
  end
36
37
 
@@ -42,4 +43,4 @@ module Quickbase
42
43
  Quickbase::API.new(self)
43
44
  end
44
45
  end
45
- end
46
+ end
@@ -1,21 +1,24 @@
1
1
  module Quickbase
2
2
  class Helper
3
- def self.hash_to_xml(hash)
4
- hash.map{|key,value|
3
+ def self.hash_to_xml(my_hash)
4
+ my_hash.map do |k,v|
5
+ key = k.to_s.encode(xml: :text)
6
+ value = v.to_s.encode(xml: :text)
5
7
  "<#{key}>#{value}</#{key}>"
6
- }
8
+ end
7
9
  end
8
-
9
- def self.generate_xml(params)
10
- Nokogiri::XML("<qdbapi>#{params.join}</qdbapi>")
10
+
11
+ def self.generate_xml(xml_input)
12
+ # xml_input is an array of xml strings
13
+ # you can use hash_to_xml to generate it
14
+ Nokogiri::XML("<qdbapi>#{xml_input.join}</qdbapi>")
11
15
  end
12
-
16
+
13
17
  def self.generate_fields(fields)
14
- fields.map{|key,value|
15
- field = "<field "
16
- fid = (key =~ /^[-+]?[0-9]+$/) ? field.concat('fid="'+key.to_s+'"') : field.concat('name="'+key.to_s+'"')
17
- field.concat(">#{value}</field>")
18
- }
18
+ fields.map do |key,value|
19
+ attr_name = (key =~ /^[-+]?[0-9]+$/) ? 'fid' : 'name'
20
+ "<field #{attr_name}=#{key.to_s.encode(xml: :attr)}>#{value.to_s.encode(xml: :text)}</field>"
21
+ end
19
22
  end
20
23
  end
21
- end
24
+ end
@@ -11,9 +11,8 @@ module Quickbase
11
11
  http_proxy = config[:http_proxy] || ENV['http_proxy']
12
12
  setup_proxy(http_proxy) if http_proxy
13
13
 
14
- qb_params[:ticket] = auth_ticket config
15
- qb_params[:apptoken] = config[:apptoken]
16
14
  qb_params[:dbid] = config[:dbid]
15
+ qb_params[:usertoken] = config[:usertoken]
17
16
  end
18
17
 
19
18
  def post(quickbase_action, params = [])
@@ -59,8 +58,4 @@ module Quickbase
59
58
  end
60
59
  end
61
60
  end
62
-
63
- class Http < HTTP
64
- puts "Class Http will be deprecated. Please use HTTP instead."
65
- end
66
- end
61
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{quickbase}
3
- s.version = "0.0.12"
3
+ s.version = "0.1.0"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Artem Kalinchuk"]
@@ -13,6 +13,8 @@ Gem::Specification.new do |s|
13
13
  s.rubyforge_project = %q{quickbase}
14
14
  s.rubygems_version = %q{1.8.5}
15
15
  s.summary = %q{Quickbase Ruby Gem}
16
+ s.homepage = 'https://github.com/kalinchuk/quickbase'
17
+ s.license = 'MIT'
16
18
  s.add_dependency(%q<nokogiri>, [">= 0"])
17
19
  s.add_dependency(%q<httparty>, [">= 0"])
18
20
  s.add_dependency(%q<activesupport>, [">= 0"])
@@ -4,80 +4,91 @@ require 'pp'
4
4
  require 'spec_helper'
5
5
 
6
6
  #fill in your own quickbase account / database
7
- Quickbase::Connection.username = ""
8
- Quickbase::Connection.password = ""
9
- Quickbase::Connection.org = ""
10
- apptoken = ""
11
- dbid = ""
7
+ Quickbase::Connection.username = "username"
8
+ Quickbase::Connection.password = "password"
9
+ Quickbase::Connection.org = "intuitcorp"
10
+ apptoken = "apptoken"
11
+ dbid = "dbid"
12
12
 
13
13
  describe Quickbase::Connection do
14
+ let(:connection) { described_class.new(:apptoken => apptoken, :dbid => dbid) }
15
+ let(:connection_hash) do
16
+ {
17
+ apptoken: connection.apptoken,
18
+ dbid: connection.dbid,
19
+ hours: connection.hours,
20
+ org: connection.org,
21
+ password: connection.password,
22
+ username: connection.username
23
+ }
24
+ end
25
+
26
+ let(:default_values_hash) do
27
+ {
28
+ apptoken: apptoken,
29
+ dbid: dbid,
30
+ hours: nil,
31
+ org: described_class.org,
32
+ password: described_class.password,
33
+ username: described_class.username
34
+ }
35
+ end
36
+
14
37
  describe "initialize" do
15
38
  it "initializes successfully" do
16
- quickbase = Quickbase::Connection.new(:apptoken => apptoken, :dbid => dbid)
17
-
18
- connection_hash = {
19
- :apptoken => quickbase.apptoken,
20
- :dbid => quickbase.dbid,
21
- :hours => quickbase.hours,
22
- :org => quickbase.org,
23
- :password => quickbase.password,
24
- :username => quickbase.username
25
- }
26
-
27
- default_values_hash = {
28
- :apptoken => apptoken,
29
- :dbid => dbid,
30
- :hours => nil,
31
- :org => Quickbase::Connection.org,
32
- :password => Quickbase::Connection.password,
33
- :username => Quickbase::Connection.username
34
- }
35
-
36
- connection_hash.should == default_values_hash
39
+ expect(connection_hash).to eq default_values_hash
37
40
  end
38
41
  end
39
42
  end
40
43
 
41
44
  describe Quickbase::Helper do
42
45
  describe "self.hash_to_xml" do
43
- it "creates XML out of a hash" do
44
- hash = {:test => "this is the content of the test tag", :test2 => "contents of test2"}
45
-
46
- Quickbase::Helper.hash_to_xml(hash).join.should == "<test>this is the content of the test tag</test><test2>contents of test2</test2>"
47
- end
46
+ let(:params) { {test: "this is the content of the test tag", test2: "contents of test2"} }
47
+ let(:result) { ["<test>this is the content of the test tag</test>", "<test2>contents of test2</test2>"] }
48
+
49
+ subject { described_class.hash_to_xml(params) }
50
+
51
+ it { is_expected.to eq result }
48
52
  end
49
-
53
+
50
54
  describe "self.generate_xml" do
51
- it "returns a formatted Quickbase XML" do
52
- hash = {:test => "this is the content of the test tag", :test2 => "contents of test2"}
53
- Quickbase::Helper.generate_xml(Quickbase::Helper.hash_to_xml(hash)).to_s.should == Nokogiri::XML("<qdbapi><test>this is the content of the test tag</test><test2>contents of test2</test2></qdbapi>").to_s
55
+ let(:input) { ["<test>this is the content of the test tag</test>", "<test2>contents of test2</test2>"] }
56
+ let(:expect_xml) { Nokogiri::XML("<qdbapi><test>this is the content of the test tag</test><test2>contents of test2</test2></qdbapi>") }
57
+
58
+ subject { described_class.generate_xml(input).to_s }
59
+
60
+ it 'returns a formatted Quickbase XML' do
61
+ expect(subject).to eq expect_xml.to_s
54
62
  end
55
63
  end
56
-
64
+
57
65
  describe "self.generate_fields" do
58
- it "creates an array of tags with all the fields" do
59
- fields = {:first_name => "John", :last_name => "Smith"}
60
- Quickbase::Helper.generate_fields(fields).should == ["<field name=\"first_name\">John</field>", "<field name=\"last_name\">Smith</field>"]
61
- end
66
+ let(:fields) { {first_name: "John", last_name: "Smith"} }
67
+ let(:result) { ["<field name=\"first_name\">John</field>", "<field name=\"last_name\">Smith</field>"] }
68
+
69
+ subject { described_class.generate_fields(fields) }
70
+
71
+ it { is_expected.to eq result }
62
72
  end
63
73
  end
64
74
 
65
75
  describe Quickbase::API do
66
- describe "do_query" do
67
- it "queries for data" do
68
- quickbase = Quickbase::Connection.new(:apptoken => apptoken, :dbid => dbid)
69
-
70
- results = quickbase.api.do_query(:query => "{'1'.XEX.'1'}", :clist => "1.2", :slist => "1")
71
- results.length.should_not == 0
72
- end
76
+ let(:connection) { Quickbase::Connection.new(apptoken: apptoken, dbid: dbid) }
77
+ let(:api) { connection.api }
78
+
79
+ describe "do_query", vcr: {cassette_name: 'do_query'} do
80
+ subject { api.do_query(query: "{'1'.XEX.'1'}", clist: "1.2", slist: "1") }
81
+
82
+ it { is_expected.to eq [{"1"=>"1280355979800", "2"=>"1280355979800"}, {"1"=>"1280355979800", "2"=>"1280355979800"}] }
73
83
  end
74
-
75
- describe "do_query_return_xml" do
76
- it "return xml" do
77
- quickbase = Quickbase::Connection.new(:apptoken => apptoken, :dbid => dbid)
78
-
79
- xml = quickbase.api.do_query_return_nokogiri_obj(:query => "{'1'.XEX.'1'}", :clist => "1.2", :slist => "1")
80
- xml.class.to_s.should == "Nokogiri::XML::Document"
84
+
85
+ describe "do_query_return_xml", vcr: {cassette_name: 'do_query'} do
86
+ let(:xml_response) { IO.read('./spec/fixtures/xml_response.xml') }
87
+ subject { api.do_query_return_nokogiri_obj(query: "{'1'.XEX.'1'}", clist: "1.2", slist: "1") }
88
+
89
+ it "returns xml" do
90
+ expect(subject).to be_a_kind_of Nokogiri::XML::Document
91
+ expect(subject.to_s).to eq xml_response
81
92
  end
82
93
  end
83
- end
94
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Artem Kalinchuk
@@ -14,49 +13,43 @@ dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: nokogiri
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: httparty
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activesupport
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: The Quickbase Gem provides integration access to the Intuit Quickbase
@@ -66,40 +59,40 @@ executables: []
66
59
  extensions: []
67
60
  extra_rdoc_files: []
68
61
  files:
69
- - lib/quickbase.rb
70
- - quickbase.gemspec
71
62
  - README.rdoc
72
63
  - lib/classes/api.rb
73
64
  - lib/classes/connection.rb
74
65
  - lib/classes/helper.rb
75
66
  - lib/classes/http.rb
67
+ - lib/quickbase.rb
68
+ - quickbase.gemspec
76
69
  - spec/quickbase_spec.rb
77
- homepage:
78
- licenses: []
70
+ homepage: https://github.com/kalinchuk/quickbase
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
79
74
  post_install_message:
80
75
  rdoc_options:
81
- - --line-numbers
82
- - --inline-source
83
- - --title
76
+ - "--line-numbers"
77
+ - "--inline-source"
78
+ - "--title"
84
79
  - Quickbase
85
80
  require_paths:
86
81
  - lib
87
82
  required_ruby_version: !ruby/object:Gem::Requirement
88
- none: false
89
83
  requirements:
90
- - - ! '>='
84
+ - - ">="
91
85
  - !ruby/object:Gem::Version
92
86
  version: '0'
93
87
  required_rubygems_version: !ruby/object:Gem::Requirement
94
- none: false
95
88
  requirements:
96
- - - ! '>='
89
+ - - ">="
97
90
  - !ruby/object:Gem::Version
98
91
  version: '1.2'
99
92
  requirements: []
100
93
  rubyforge_project: quickbase
101
- rubygems_version: 1.8.23.2
94
+ rubygems_version: 2.4.6
102
95
  signing_key:
103
- specification_version: 3
96
+ specification_version: 4
104
97
  summary: Quickbase Ruby Gem
105
98
  test_files: []