formi9 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 48e1d649b4afd311e7048298d198f30a8fb65efbef72d9afcd3f9738b8ae76fc
4
+ data.tar.gz: 84738ae67a055f61bf15f3cbae2a5d349e4f101cec14b74c559c7edfa3983548
5
+ SHA512:
6
+ metadata.gz: 015fb06e3e00222c337a12fd40ffa9e7aa2b13ab395fff6259ba1a411437d91e52dd299e2649403da9a0ac5299dad7d330668e6bb9f19a4575c903e24e70f4bd
7
+ data.tar.gz: 2d3cb07e3b2c3fb99194edd3ebdc9b80ecaaba85775a74099e49589b26f50309d4e0e9c8607aac19148e83494288ce11a44c7b77b80a71383399458620d4f13b
data/.gitignore ADDED
@@ -0,0 +1,27 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .rspec_status
11
+ *.gem
12
+ *.rbc
13
+ .DS_Store
14
+ .bundle
15
+ .rvmrc
16
+ .ruby-version
17
+ .yardoc
18
+ .rake_tasks~
19
+ Gemfile.lock
20
+ coverage/*
21
+ doc/*
22
+ log/*
23
+ pkg/*
24
+ .idea/*
25
+
26
+ # Vim Swap file
27
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.2
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at xiaorong.ruby@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in formi9.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Ryan Lv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # formi9
2
+
3
+ A Ruby API wrapper for [formi9.com](https://www.formi9.com/FormI9Api/swagger/ui/index) [![Build Status](https://api.travis-ci.com/helloworld1812/formi9.svg?branch=master)](https://travis-ci.com/github/helloworld1812/formi9)
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'formi9'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle install
17
+
18
+ You can use an initializer to configure this gem, please put the following code into `config/initializers/formi9_complicance.rb`
19
+
20
+ ```ruby
21
+ Formi9.configure do |config|
22
+ config.partner_id = 'Your Partner Id'
23
+ config.username = 'Your username'
24
+ config.password = 'Your password'
25
+ # config.b2b_encryption_key = 'key'
26
+ # config.b2b_encryption_iv = 'iv'
27
+ end
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ## Create a company
33
+
34
+ ```ruby
35
+ Formi9.create_company_with_mou(options)
36
+ ```
37
+
38
+
39
+ ## Create section 1 for employee
40
+
41
+ ```ruby
42
+ Formi9.create_section1(options)
43
+ ```
44
+ the response contains
45
+
46
+ - resultId
47
+ - auto login link for employee to fill the form section 1
48
+
49
+
50
+ ## Create section 2 for HR
51
+
52
+ ```ruby
53
+ Formi9.create_section2
54
+ ```
55
+
56
+ ### Retrieve the status of form
57
+
58
+ ```ruby
59
+ Formi9.case_status(result_id, auto_login_url: true)
60
+ ```
61
+
62
+ ### Download the PDF of formi9
63
+
64
+ ```ruby
65
+ Formi9.download_pdf(result_id, {
66
+ printSignatures: true,
67
+ printNotes: true,
68
+ printEverify: true,
69
+ printDocs: true,
70
+ printAudit_trail: true
71
+ })
72
+ ```
73
+
74
+ ## Development
75
+
76
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
77
+
78
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
79
+
80
+ ## Contributing
81
+
82
+ Bug reports and pull requests are welcome on GitHub at https://github.com/helloworld1812/formi9. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/helloworld1812/formi9/blob/master/CODE_OF_CONDUCT.md).
83
+
84
+ ## Reference
85
+
86
+ 1. formi9.com [API documentation](https://www.formi9.com/FormI9Api/swagger/ui/index)
87
+
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
92
+
93
+ ## Code of Conduct
94
+
95
+ Everyone interacting in the Formi9 project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/helloworld1812/formi9/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "formi9"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ # Pry.start
12
+
13
+ # set rails cache
14
+ require 'rails'
15
+ Rails.cache = ActiveSupport::Cache.lookup_store(:memory_store)
16
+
17
+
18
+ require "irb"
19
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/formi9.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ require_relative 'lib/formi9/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "formi9"
5
+ spec.version = Formi9::VERSION
6
+ spec.authors = ["Ryan Lv"]
7
+ spec.email = ["tech@workstream.is"]
8
+
9
+ spec.summary = 'A Ruby API wrapper for formi9.com'
10
+ spec.description = spec.summary
11
+ spec.homepage = 'https://github.com/helloworld1812/formi9'
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = 'https://github.com/helloworld1812/formi9'
19
+ spec.metadata["changelog_uri"] = 'https://github.com/helloworld1812/formi9/CHANGELOG.md'
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "> 2.0.0"
31
+ spec.add_development_dependency "rake", ">= 12.3.3"
32
+ spec.add_development_dependency "rspec", ">= 3.9.0"
33
+ spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "webmock"
35
+
36
+ spec.add_runtime_dependency 'faraday'
37
+ spec.add_runtime_dependency 'rails', ">= 5.0.0"
38
+ spec.add_runtime_dependency 'faraday_middleware'
39
+ end
@@ -0,0 +1,30 @@
1
+ require 'faraday'
2
+
3
+ module FaradayMiddleWare
4
+ class RaiseFormi9HttpException < Faraday::Middleware
5
+ def initialize(app)
6
+ super(app)
7
+ end
8
+
9
+ def call(env)
10
+ @app.call(env).on_complete do |response|
11
+ case response.status.to_i
12
+ when 400
13
+ raise Formi9::BadRequest.new(response)
14
+ when 401
15
+ raise Formi9::Unauthorized.new(response)
16
+ when 404
17
+ raise Formi9::NotFound.new(response)
18
+ when 500
19
+ raise Formi9::InternalServerError.new(response)
20
+ when 502
21
+ raise Formi9::BadGateway.new(response)
22
+ when 503
23
+ raise Formi9::ServiceUnavailable.new(response)
24
+ when 504
25
+ raise Formi9::GatewayTimeout.new(response)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/formi9/api.rb ADDED
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../connection', __FILE__)
2
+ require File.expand_path('../request', __FILE__)
3
+ require File.expand_path('../oauth', __FILE__)
4
+
5
+ module Formi9
6
+ # @private
7
+ class API
8
+ # @private
9
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
10
+
11
+ # Creates a new API
12
+ def initialize(options={})
13
+ options = Formi9.options.merge(options)
14
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
15
+ send("#{key}=", options[key])
16
+ end
17
+ end
18
+
19
+ def config
20
+ conf = {}
21
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
22
+ conf[key] = send key
23
+ end
24
+ conf
25
+ end
26
+
27
+ include Connection
28
+ include Request
29
+ include OAuth
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ require "base64"
2
+ require 'openssl'
3
+ require 'faraday'
4
+
5
+ module Formi9
6
+ class Client
7
+ module B2b
8
+
9
+ # options = {
10
+ # b2b_username: 'Ryan Lyu'
11
+ # company_id: 'workstreamdemo',
12
+ # request_id: 'AUniqueId',
13
+ # result_id: 'AUniqueId'
14
+ # }
15
+ def b2b_direct_link(options)
16
+ string = "AlliancePartnerID=#{CGI.escape(partner_id)}"
17
+ string << "&AlliancePartnerLogin=#{CGI.escape(username)}"
18
+ string << "&AlliancePartnerPassword=#{CGI.escape(password)}"
19
+ string << "&AlliancePartnerCompanyID=#{CGI.escape(options[:company_id])}"
20
+ string << "&Target=DirectLink&B2BUserName=#{CGI.escape(options[:b2b_username])}"
21
+ string << "&RequestID=#{CGI.escape(options[:request_id])}"
22
+ string << "&ResultID=#{CGI.escape(options[:result_id])}&"
23
+
24
+ data = b2b_encrypt(string)
25
+
26
+ "https://www.formi9.com/FormI9Verify/FormI9LoginService.aspx?EPID=#{partner_id}&EDATA=#{data}"
27
+ end
28
+
29
+
30
+ def b2b_encrypt(string)
31
+ cipher = b2b_encryption_algorithm.new(b2b_encryption_cipher_mode)
32
+ cipher.encrypt
33
+ cipher.key = b2b_encryption_key
34
+ cipher.iv = b2b_encryption_iv
35
+ encrypted_string = cipher.update(string)
36
+ encrypted_string << cipher.final
37
+
38
+ base64_string = Base64.strict_encode64(encrypted_string)
39
+ escaped_data = CGI.escape(base64_string)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ module Formi9
2
+ class Client
3
+ # Defines methods related to companies
4
+ module Companies
5
+
6
+ # Get company settings, if there are no settings saved, anempty response if given.
7
+ def get_company_info(company_id)
8
+ get("companies/#{company_id}")
9
+ end
10
+
11
+ def create_company_with_mou(options)
12
+ post('companies/mou', options)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module Formi9
2
+ class Client
3
+ # Defines methods related to formi9
4
+ module Eformi9
5
+ def create_section1(options={})
6
+ post('eformi9/section1', options)
7
+ end
8
+
9
+ def update_section1(options={})
10
+ post('eformi9/section1/edit', options)
11
+ end
12
+
13
+ def create_section2(options={})
14
+ post('eformi9/section2', options)
15
+ end
16
+
17
+ def case_status(result_id, options={})
18
+ get("eformi9/status?request.resultId=#{result_id}&request.generateAutoLoginUrl=#{!!options[:auto_login_url]}")
19
+ end
20
+
21
+ def download_pdf(result_id, options={})
22
+ options = options.with_indifferent_access
23
+ params = []
24
+ [:printSignatures, :printNotes, :printEVerify, :printDocs, :printAuditTrail].each do |key|
25
+ params << "#{key}=true" if options[:key]
26
+ end
27
+ get("eformi9/#{result_id}/pdf?#{params.join('&')}")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Formi9
2
+ class Client
3
+ # Defines methods related to Options
4
+ module Options
5
+ # Get company option by option name.
6
+ def get_company_option(company_id, option_name)
7
+ get("companies/#{company_id}/options/#{option_name}").body
8
+ end
9
+
10
+ # Create or update a option for a specific company
11
+ def update_company_option(company_id, option_name, payload={})
12
+ put("companies/#{company_id}/options/#{option_name}", payload)
13
+ end
14
+
15
+ # Get enabled options of specific company
16
+ def get_company_active_options(company_id)
17
+ get("companies/#{company_id}/options/active").body
18
+ end
19
+
20
+ # preset options for a specific company.
21
+ def create_preset2(company_id, preset_group)
22
+ post("companies/#{company_id}/options/preset2?presetGroup=#{preset_group}")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module Formi9
2
+ class Client
3
+ # Defines methods related to Services
4
+ module Services
5
+ # Add a service for a company
6
+ def create_company_service(company_id, service_name)
7
+ post("companies/#{company_id}/services/#{service_name}")
8
+ end
9
+
10
+ # Get all services of a company.
11
+ def get_company_services(company_id)
12
+ get("companies/#{company_id}/services").body
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Formi9
2
+ class Client < API
3
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each{|f| require f}
4
+
5
+
6
+ include Formi9::Client::Companies
7
+ include Formi9::Client::Eformi9
8
+ include Formi9::Client::B2b
9
+ include Formi9::Client::Options
10
+ include Formi9::Client::Services
11
+ end
12
+ end
@@ -0,0 +1,109 @@
1
+ require 'faraday'
2
+ require 'openssl'
3
+ require File.expand_path('../version', __FILE__)
4
+
5
+ module Formi9
6
+ # Defines constants and methods related to configuration
7
+ module Configuration
8
+ # An array of valid keys in the options hash when configuring a {Formi9::API}
9
+ VALID_OPTIONS_KEYS = [
10
+ :partner_id,
11
+ :username,
12
+ :password,
13
+ :adapter,
14
+ :connection_options,
15
+ :host,
16
+ :endpoint,
17
+ :format,
18
+ :proxy,
19
+ :user_agent,
20
+ :per_page,
21
+ :timeout,
22
+ :ssl_verify,
23
+ :open_timeout,
24
+ :b2b_encryption_algorithm,
25
+ :b2b_encryption_cipher_mode,
26
+ :b2b_encryption_key,
27
+ :b2b_encryption_iv,
28
+ ].freeze
29
+
30
+ # By default, don't set an access token
31
+ DEFAULT_ACCESS_TOKEN = nil
32
+
33
+ # By default, return 20 resources per page when there is an pagination.
34
+ DEFAULT_PER_PAGE = 20
35
+
36
+ # The adapter that will be used to connect if none is set
37
+ #
38
+ # @note The default faraday adapter is Net::HTTP.
39
+ DEFAULT_ADAPTER = Faraday.default_adapter
40
+
41
+ # By default, don't set connection options.
42
+ DEFAULT_CONNECTION_OPTIONS = {}
43
+
44
+ # Default timeout time is 20 seconds
45
+ DEFAULT_TIMEOUT = 20
46
+
47
+ # By default, the open timeout is 20 seconds.
48
+ DEFAULT_OPEN_TIMEOUT = 20
49
+
50
+ DEFAULT_SSL_VERIFY = false
51
+
52
+ # The endpoint that will be used to connect if none is set
53
+ DEFAULT_ENDPOINT = 'https://www.formi9.com/FormI9Api/partner/v2.0/'.freeze
54
+
55
+ # The response format appended to the path and sent in the 'Accept' header if none is set
56
+ #
57
+ # @note JSON is the only available format at this time
58
+ DEFAULT_FORMAT = :json
59
+
60
+ DEFAULT_B2B_ENCRYPTION_ALGORITHM = OpenSSL::Cipher::AES256
61
+
62
+ DEFAULT_B2B_ENCRYPTION_CIPHER_MODE = :CBC
63
+
64
+ # By default, don't use a proxy server
65
+ DEFAULT_PROXY = nil
66
+
67
+ # The user agent that will be sent to the API endpoint if none is set
68
+ DEFAULT_USER_AGENT = "formi9.com Ruby Gem #{Formi9::VERSION}".freeze
69
+
70
+ # An array of valid request/response formats
71
+ VALID_FORMATS = [:json].freeze
72
+
73
+ # @private
74
+ attr_accessor *VALID_OPTIONS_KEYS
75
+
76
+ # When this module is extended, set all configuration options to their default values
77
+ def self.extended(base)
78
+ base.reset
79
+ end
80
+
81
+ # Convenience method to allow configuration options to be set in a block
82
+ def configure
83
+ yield self
84
+ end
85
+
86
+ # Create a hash of options and their values
87
+ def options
88
+ VALID_OPTIONS_KEYS.inject({}) do |option, key|
89
+ option.merge!(key => send(key))
90
+ end
91
+ end
92
+
93
+ # Reset all configuration options to defaults
94
+ def reset
95
+ self.adapter = DEFAULT_ADAPTER
96
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
97
+ self.endpoint = DEFAULT_ENDPOINT
98
+ self.format = DEFAULT_FORMAT
99
+ self.proxy = DEFAULT_PROXY
100
+ self.user_agent = DEFAULT_USER_AGENT
101
+ self.per_page = DEFAULT_PER_PAGE
102
+ self.timeout = DEFAULT_TIMEOUT
103
+ self.open_timeout = DEFAULT_OPEN_TIMEOUT
104
+ self.ssl_verify = DEFAULT_SSL_VERIFY
105
+ self.b2b_encryption_algorithm = DEFAULT_B2B_ENCRYPTION_ALGORITHM
106
+ self.b2b_encryption_cipher_mode = DEFAULT_B2B_ENCRYPTION_CIPHER_MODE
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,35 @@
1
+ require 'faraday_middleware'
2
+ Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each{|f| require f}
3
+
4
+ module Formi9
5
+ module Connection
6
+
7
+ private
8
+
9
+ def connection
10
+ options = {
11
+ headers: {
12
+ "Accept" => "application/#{format}; charset=utf-8",
13
+ "User-Agent" => Formi9.user_agent,
14
+ },
15
+ proxy: proxy,
16
+ url: endpoint,
17
+ ssl: { verify: ssl_verify }
18
+ }.merge(connection_options)
19
+
20
+ Faraday::Connection.new(options) do |conn|
21
+ conn.authorization :Bearer, access_token
22
+ # https://github.com/lostisland/faraday/issues/417#issuecomment-223413386
23
+ conn.options[:timeout] = timeout
24
+ conn.options[:open_timeout] = open_timeout
25
+ conn.request :json
26
+
27
+ conn.use FaradayMiddleWare::RaiseFormi9HttpException
28
+ conn.request :retry, max: 3, interval: 0.1, exceptions: [Errno::ECONNREFUSED, Faraday::ConnectionFailed]
29
+ conn.response :json, content_type: /\bjson$/
30
+ conn.adapter Faraday.default_adapter
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,55 @@
1
+ module Formi9
2
+ # Part1 API error
3
+ # Custom error class for rescuing from all formi9.com errors
4
+ class Error < StandardError
5
+ attr_reader :http_method, :url, :errors
6
+
7
+ def initialize(response)
8
+ super
9
+ @response = response.dup
10
+ @http_method = response.method.to_s
11
+ @url = response.url
12
+ end
13
+
14
+ def message
15
+ <<-HEREDOC
16
+ URL: #{@response.url}
17
+ method: #{@response.method}
18
+ response status: #{@response.status}
19
+ response body: #{@response.response.body}
20
+ HEREDOC
21
+ end
22
+ end
23
+
24
+ # Raised when formi9.com returns the HTTP status code 400
25
+ class BadRequest < Error; end
26
+
27
+ # Raised when formi9.com returns the HTTP status code 401
28
+ class Unauthorized < Error; end
29
+
30
+ # Raised when formi9.com returns the HTTP status code 404
31
+ class NotFound < Error; end
32
+
33
+ # Raised when formi9.com returns the HTTP status code 500
34
+ class InternalServerError < Error; end
35
+
36
+ # Raised when formi9.com returns the HTTP status code 502
37
+ class BadGateway < Error; end
38
+
39
+ # Raised when formi9.com returns the HTTP status code 503
40
+ class ServiceUnavailable < Error; end
41
+
42
+ # Raised when formi9.com returns the HTTP status code 504
43
+ class GatewayTimeout < Error; end
44
+
45
+
46
+ # Part2 Non-API error
47
+ # Raised when client fails to provide required parameters.
48
+ class MissingRequiredArgument < StandardError; end
49
+
50
+ # Raised when configuration is missing
51
+ class MissingRequiredConfigurationt < StandardError; end
52
+
53
+ # Invalid username or password
54
+ class CredentialAreInvalid < StandardError; end
55
+ end
@@ -0,0 +1,36 @@
1
+ require 'active_support/core_ext/string/conversions'
2
+
3
+ module Formi9
4
+ module OAuth
5
+ def access_token
6
+ token = Rails.cache.read(access_token_cache_key)
7
+
8
+ if token.present?
9
+ return token
10
+ else
11
+ reset_token
12
+ Rails.cache.read(access_token_cache_key)
13
+ end
14
+ end
15
+
16
+ def reset_token
17
+ connection = Faraday.new endpoint, :ssl => {:verify => ssl_verify }
18
+ response = connection.post('login', {id: partner_id, username: username, password: password} )
19
+ raise CredentialAreInvalid.new('Credentials are missing or invalid.') if response.status != 200
20
+ body = JSON.parse(response.body)
21
+ if Rails.cache.read(access_token_cache_key).nil?
22
+ Rails.cache.write(access_token_cache_key, body['accessToken'], expires_in: token_cache_duration(body['expirationDateUtc']))
23
+ end
24
+ end
25
+
26
+ def access_token_cache_key
27
+ Digest::MD5.hexdigest([partner_id, username, password].join)
28
+ end
29
+
30
+ def token_cache_duration(timestamp)
31
+ max = 6.days.to_i
32
+ duration = timestamp.to_datetime.utc - Time.now
33
+ duration > max ? max : duration
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ require 'base64'
2
+
3
+ module Formi9
4
+ # Defines HTTP request methods
5
+ module Request
6
+ # HTTP GET request
7
+ def get(path, options={})
8
+ request(:get, path, options)
9
+ end
10
+
11
+ # HTTP POST request
12
+ def post(path, options={})
13
+ request(:post, path, options)
14
+ end
15
+
16
+ # HTTP PUT request
17
+ def put(path, options={})
18
+ request(:put, path, options)
19
+ end
20
+
21
+ # HTTP DELETE request
22
+ def delete(path, options={})
23
+ request(:delete, path, options)
24
+ end
25
+
26
+ def request(method, path, options)
27
+ response = connection.send(method) do |request|
28
+ case method
29
+ when :get, :delete
30
+ request.url(URI.encode(path), options)
31
+ when :post, :put
32
+ request.path = URI.encode(path)
33
+ request.body = options
34
+ end
35
+ end
36
+
37
+ response
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Formi9
2
+ VERSION = "0.1.7"
3
+ end
data/lib/formi9.rb ADDED
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../formi9/error', __FILE__)
2
+ require File.expand_path('../formi9/configuration', __FILE__)
3
+ require File.expand_path('../formi9/api', __FILE__)
4
+ require File.expand_path('../formi9/client', __FILE__)
5
+
6
+ module Formi9
7
+ extend Configuration
8
+
9
+ # Alias for Formi9::Client.new
10
+ #
11
+ # @return [Formi9::Client]
12
+ def self.client(options={})
13
+ Formi9::Client.new(options)
14
+ end
15
+
16
+ # Delegate to Formi9::Client
17
+ def self.method_missing(method, *args, &block)
18
+ return super unless client.respond_to?(method)
19
+ client.send(method, *args, &block)
20
+ end
21
+
22
+ # Delegate to Formi9::Client
23
+ def self.respond_to?(method, include_all=false)
24
+ return client.respond_to?(method, include_all) || super
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: formi9
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Lv
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 12.3.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 12.3.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.9.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.9.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 5.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 5.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: faraday_middleware
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: A Ruby API wrapper for formi9.com
126
+ email:
127
+ - tech@workstream.is
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - CODE_OF_CONDUCT.md
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/console
141
+ - bin/setup
142
+ - formi9.gemspec
143
+ - lib/faraday/raise_formi9_http_exception.rb
144
+ - lib/formi9.rb
145
+ - lib/formi9/api.rb
146
+ - lib/formi9/client.rb
147
+ - lib/formi9/client/b2b.rb
148
+ - lib/formi9/client/companies.rb
149
+ - lib/formi9/client/eformi9.rb
150
+ - lib/formi9/client/options.rb
151
+ - lib/formi9/client/services.rb
152
+ - lib/formi9/configuration.rb
153
+ - lib/formi9/connection.rb
154
+ - lib/formi9/error.rb
155
+ - lib/formi9/oauth.rb
156
+ - lib/formi9/request.rb
157
+ - lib/formi9/version.rb
158
+ homepage: https://github.com/helloworld1812/formi9
159
+ licenses:
160
+ - MIT
161
+ metadata:
162
+ homepage_uri: https://github.com/helloworld1812/formi9
163
+ source_code_uri: https://github.com/helloworld1812/formi9
164
+ changelog_uri: https://github.com/helloworld1812/formi9/CHANGELOG.md
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 2.3.0
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubygems_version: 3.0.8
181
+ signing_key:
182
+ specification_version: 4
183
+ summary: A Ruby API wrapper for formi9.com
184
+ test_files: []