junziqian 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b64f3ed120e160c2d5b413cbdaeeb23b187b8bbe
4
+ data.tar.gz: b9db8cfb9678ebc2fe53e9a0721635632d664a45
5
+ SHA512:
6
+ metadata.gz: 61aa917eab2244132b37f1d5099ff7784a6e66eb3e541a53531cbd820f98e5a42c7b8d72860bc47d2250360777fead9cf21adf89bd3073d26eedaf43973eb982
7
+ data.tar.gz: a86e879dfb88eea35bf243412f933fee5e08908e169c541a481af5edab15edc294cd2f4c1b4ac7ca063d31b245946d1a30f4b6d3de199a668468afd63a8a7f12
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.idea/
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.14.6
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in junziqian.gemspec
4
+ # Call 'byebug' anywhere in the code to stop execution and get a debugger console
5
+ gem 'byebug', platform: :mri
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Junziqian
2
+
3
+ Junziqian is an electronic sign contract system. This gem is an adaptor for interactive with junziqian's service.
4
+
5
+ 君子签是电子签章的一种,上传签约人,签约合同,实现电子签章或手工签约,并在三方保存,以符合一定的法律效力。
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'junziqian'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install junziqian
22
+
23
+ ## Usage
24
+
25
+ * 首先设置您的接口信息,包含请求地址,key,secret,gem通过 ENV 变量获取三个参数; 合同下载存放路径 ENV['contract_path'] (默认为/tmp)
26
+ ````
27
+ def services_url
28
+ ENV['JZQ_SERVICES_URL'] || 'http://sandbox.api.junziqian.com/services'
29
+ end
30
+
31
+ def app_key
32
+ ENV['JZQ_APP_KEY'] || 'ecf3961459a07af4'
33
+ end
34
+
35
+ def app_secret
36
+ ENV['JZQ_APP_SECRET'] || '187a255fecf3961459a07af4d2035e47'
37
+ end
38
+ ````
39
+ * 实现ping接口检测、文件上传签约、状态查询、查看链接、下载链接等等的功能,具体请看lib/junziqian/interface目录
40
+
41
+ * 回调参数校验
42
+ ````
43
+ body_hash = {
44
+ 'applyNo' => params[:applyNo],
45
+ 'identityType' => params[:identityType],
46
+ 'fullName' => params[:fullName],
47
+ 'identityCard' => params[:identityCard],
48
+ 'optTime' => params[:optTime],
49
+ 'signStatus' => params[:signStatus]
50
+ }
51
+ if params[:sign] == Junziqian::Tool::RequestTool.create_http_sign(body_hash, params[:timestamp])
52
+ ...
53
+ ...
54
+ ````
55
+ ## Development
56
+
57
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
+
59
+ 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).
60
+
61
+ ## Contributing
62
+
63
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/junziqian.
64
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "junziqian"
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
+ require "irb"
14
+ 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/junziqian.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'junziqian/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "junziqian"
8
+ spec.version = Junziqian::VERSION
9
+ spec.authors = ["方峦"]
10
+ spec.email = ["moonless@fangluandeMacBook-Pro.local"]
11
+
12
+ spec.summary = %q{支持君子签,电子签名}
13
+ spec.description = %q{ruby版本的支持君子签,电子签名的gem库}
14
+ spec.homepage = "http://github.com/orichi/junziqian"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ #spec.metadata['allowed_push_host'] = ""
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against " \
22
+ "public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", "~> 1.14"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "minitest", "~> 5.0"
35
+ end
data/lib/junziqian.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "junziqian/version"
2
+ require "junziqian/cfg/client_info"
3
+ require "junziqian/cfg/enum"
4
+ require "junziqian/tool/http_sign_utils"
5
+ require "junziqian/tool/request_tool"
6
+ require "junziqian/tool/attache_utils"
7
+ require 'junziqian/model/signatory'
8
+ require 'junziqian/interface/base_request'
9
+ require 'junziqian/interface/ping'
10
+ require 'junziqian/interface/apply_sign_file_request'
11
+ require 'junziqian/interface/detail_anony_link_request'
12
+ require 'junziqian/interface/file_link_request'
13
+
14
+ module Junziqian
15
+ # Your code goes here...
16
+ end
@@ -0,0 +1,22 @@
1
+ require 'singleton'
2
+ module Junziqian
3
+ module Cfg
4
+ class ClientInfo
5
+ include Singleton
6
+
7
+ class << self
8
+ def services_url
9
+ ENV['JZQ_SERVICES_URL'] || 'http://sandbox.api.junziqian.com/services'
10
+ end
11
+
12
+ def app_key
13
+ ENV['JZQ_APP_KEY'] || 'ecf3961459a07af4'
14
+ end
15
+
16
+ def app_secret
17
+ ENV['JZQ_APP_SECRET'] || '187a255fecf3961459a07af4d2035e47'
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,43 @@
1
+ module Junziqian
2
+ module Cfg
3
+ class Enum
4
+ # 用户身分证明类型枚举
5
+ IDCARD={"code" => 1, "type" => 0}
6
+ PASSPORT={"code" => 2, "type" => 0}
7
+ MTP={"code" => 3, "type" => 0}
8
+ RTMP={"code" => 4, "type" => 0}
9
+ BIZLIC={"code" => 11, "type" => 1}
10
+ USCC={"code" => 12, "type" => 1}
11
+ OTHER={"code" => 99, "type" => 3}
12
+
13
+ # * 验证等级
14
+ USEKEY=1
15
+ BANKCARD=2
16
+ ALIPAY=3
17
+ BANKTHREE=10
18
+ FACE=11
19
+
20
+ # * 企业类型
21
+ ENTERPRISE="0"
22
+ PUBLIC_INSTITUTION="1"
23
+
24
+ # 签章等级
25
+ GENERAL="0"
26
+ SEAL="1"
27
+ ESIGNSEAL="2"
28
+
29
+ #签字状态
30
+ NOTINIT=-1
31
+ INPROGRESS=0
32
+ COMPLETED=1
33
+ REFUSE=2
34
+ PRES=3
35
+
36
+ # 合同的处理类型,可以人签,也可以自动签
37
+ DEFAULT="0"
38
+ AUTH_SIGN="1"
39
+ ONLY_PRES="2"
40
+ AUTH_SIGN_PART='5'
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,100 @@
1
+ module Junziqian
2
+ module Interface
3
+ class ApplySignFileRequest < BaseRequest
4
+ # attr_accessor :contractName
5
+ # attr_accessor :serverCa
6
+ # attr_accessor :dealType
7
+ # attr_accessor :file
8
+ # attr_accessor :authenticationLevel
9
+ # attr_accessor :dealType
10
+ # attr_accessor :forceAuthentication
11
+ # attr_accessor :needCa
12
+ # attr_accessor :orderFlag
13
+ # attr_accessor :signLevel
14
+ # attr_accessor :sequenceInfo
15
+ # attr_accessor :
16
+ [:contractName,:serverCa,:dealType,:file,:authenticationLevel,:dealType,:forceAuthentication,:needCa,:orderFlag,:signLevel,:sequenceInfo, :signatories].each do |at|
17
+ attr_accessor at
18
+ end
19
+
20
+ def initialize(options)
21
+ tmp = []
22
+ options.each do |k, v|
23
+ if k == :signatories
24
+ options[:signatories].each do |sign|
25
+ tmp << Model::Signatory.new(sign).hash_values
26
+ end
27
+ self.signatories = "[#{tmp.join()}]"
28
+ elsif k == :file
29
+ self.file = Junziqian::Tool::AttacheUtils.new options[:file]
30
+ else
31
+ self.send("#{k}=", v) if self.respond_to?(k)
32
+ end
33
+ end
34
+ end
35
+
36
+ def version
37
+ '1.0'
38
+ end
39
+
40
+ def content_type
41
+ 'multipart/form-data'
42
+ end
43
+
44
+ def method
45
+ 'sign.apply.file'
46
+ end
47
+
48
+ def ignores_params
49
+ [:file]
50
+ end
51
+
52
+ def query_params
53
+ #{contractName: contractName, serverCa: serverCa, dealType: dealType, file: file}.merge({signatories: @signatories})
54
+ [:contractName,:serverCa,:dealType,:file,:authenticationLevel,:dealType,:forceAuthentication,:needCa,:orderFlag,:signLevel,:sequenceInfo, :signatories].inject({}) do |hash,item|
55
+ (hash[item] = self.send(item)) if self.send(item).present?
56
+ hash
57
+ end
58
+ end
59
+
60
+ def request
61
+ Junziqian::Tool::RequestTool.do_post_by_requestObj(self)
62
+ end
63
+
64
+ def demo
65
+ signatories = [{
66
+ userType: Junziqian::Cfg::Enum::IDCARD['type'],
67
+ identityType: Junziqian::Cfg::Enum::IDCARD['code'],
68
+ fullName: '张三',
69
+ identityCard: '360732198908110099',
70
+ mobile: '15123649601',
71
+ signLevel: Junziqian::Cfg::Enum::GENERAL,
72
+ noNeedVerify: 0,
73
+ serverCaAuto: 1,
74
+ orderNum: 1,
75
+ chapteJson: '['+ {'page' => 0, 'chaptes' => [{"offsetX" => 0.12, "offsetY" => 0.23},{"offsetX" => 0.45, "offsetY" => 0.67}]}.to_json+']'
76
+ },{userType: Junziqian::Cfg::Enum::BIZLIC['type'],
77
+ identityType: Junziqian::Cfg::Enum::BIZLIC['code'],
78
+ fullName: '测试公司',
79
+ identityCard: '461313456461316',
80
+ email: '1244268365@qq.com',
81
+ orderNum: 2,
82
+ signLevel: Junziqian::Cfg::Enum::SEAL,
83
+ serverCaAuto: 1,
84
+ chapteJson: "["+[{'page' => 1,'chaptes' => [{"offsetX" => 0.31, "offsetY" => 0.72},{"offsetX" => 0.72, "offsetY" => 0.72}]}.to_json, {'page' => 2, 'chaptes' => [{"offsetX" => 0.8, "offsetY" => 0.82}]}.to_json].join()+']'
85
+ }]
86
+ demo1 = {
87
+ file: '/Users/moonless/Documents/demo_contract.pdf',
88
+ contractName: '合同0001',
89
+ signatories: signatories,
90
+ serverCa: 1,
91
+ dealType: Junziqian::Cfg::Enum::AUTH_SIGN,
92
+ orderFlag: 1
93
+ }
94
+ req = Junziqian::Interface::ApplySignFileRequest.new demo1
95
+ #=> {"applyNo"=>"APL882159678413475840", "success"=>true}
96
+ #=> {"applyNo"=>"APL882164292533751808", "success"=>true}
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,17 @@
1
+ module Junziqian
2
+ module Interface
3
+ class BaseRequest
4
+ def content_type
5
+ 'application/x-www-form-urlencoded; charset=UTF-8'
6
+ end
7
+
8
+ def query_params
9
+ {}
10
+ end
11
+
12
+ def ignores_params
13
+ []
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ module Junziqian
2
+ module Interface
3
+ class DetailAnonyLinkRequest < BaseRequest
4
+ attr_accessor :applyNo
5
+
6
+ def initialize apply_no
7
+ self.applyNo = apply_no
8
+ end
9
+ def version
10
+ '1.0'
11
+ end
12
+
13
+ def method
14
+ 'sign.link.anony.detail'
15
+ end
16
+
17
+ def ingore_signs
18
+ []
19
+ end
20
+
21
+ def query_params
22
+ {applyNo: applyNo}
23
+ end
24
+
25
+
26
+
27
+ def request
28
+ Tool::RequestTool.do_post_by_requestObj(self)
29
+ # applyNo=APL882159678413475840=> {"link"=> "http://sandbox.junziqian.com/applaySign/toDetailAnony?timestamp=1499160325399&applyNo=APL882159678413475840&sign=a693a313a271b60a53c5c0324f14e7026f89b9f8", "success"=>true}
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module Junziqian
2
+ module Interface
3
+ class FileLinkRequest < BaseRequest
4
+ attr_accessor :applyNo
5
+
6
+ def initialize apply_no
7
+ self.applyNo = apply_no
8
+ end
9
+ def version
10
+ '1.0'
11
+ end
12
+
13
+ def method
14
+ 'sign.link.file'
15
+ end
16
+
17
+ def ingore_signs
18
+ []
19
+ end
20
+
21
+ def query_params
22
+ {applyNo: applyNo}
23
+ end
24
+
25
+ def file_path
26
+ Dir.mkdir(ENV['contract_path']) if ENV['contract_path'] && Dir.exist?(ENV['contract_path'])
27
+ ENV['contract_path'] || '/tmp'
28
+ end
29
+
30
+
31
+
32
+ def request
33
+ result = Tool::RequestTool.do_post_by_requestObj(self)
34
+ if result['success'] == true
35
+ link = result['link']
36
+ system(`curl '#{link}' -o #{file_path}/applyNo#{self.applyNo}.pdf`)
37
+ else
38
+ 'error'
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ module Junziqian
2
+ module Interface
3
+ class Ping < BaseRequest
4
+ def version
5
+ '1.0'
6
+ end
7
+
8
+ def method
9
+ 'ping'
10
+ end
11
+
12
+ def ingore_signs
13
+ []
14
+ end
15
+
16
+
17
+
18
+ def request
19
+ Tool::RequestTool.do_post_by_requestObj(self)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+ module Junziqian
2
+ module Interface
3
+ class PresFileLink < BaseRequest
4
+ attr_accessor :applyNo
5
+ attr_accessor :signatory
6
+
7
+ def initialize options
8
+ self.applyNo = options[:apply_no]
9
+ self.signatory = Junziqian::Model::Signatory.new(options[:signatory]).hash_values
10
+ end
11
+
12
+ def version
13
+ '1.0'
14
+ end
15
+
16
+ def method
17
+ 'pres.link.file'
18
+ end
19
+
20
+ def ingore_signs
21
+ []
22
+ end
23
+
24
+ def query_params
25
+ {applyNo: applyNo, signatory: signatory}
26
+ end
27
+
28
+ def file_path
29
+ Dir.mkdir(ENV['contract_path']) if ENV['contract_path'] && Dir.exist?(ENV['contract_path'])
30
+ ENV['contract_path'] || '/tmp'
31
+ end
32
+
33
+
34
+
35
+ def request
36
+ result = Tool::RequestTool.do_post_by_requestObj(self)
37
+ if result['success'] == true
38
+ link = result['link']
39
+ system(`curl '#{link}' -o #{file_path}/applyNo#{self.applyNo}.pdf`)
40
+ else
41
+ result
42
+ end
43
+ end
44
+
45
+ def demo
46
+ hash = {signatory: {userType: Junziqian::Cfg::Enum::IDCARD['type'],
47
+ identityType: Junziqian::Cfg::Enum::IDCARD['code'],
48
+ fullName: '张三',
49
+ identityCard: '360732198908110099'},
50
+ apply_no: 'APL882159678413475840'}
51
+ req = Junziqian::Interface::PresFileLink.new(hash)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ module Junziqian
2
+ module Interface
3
+ class SignStatusRequest < BaseRequest
4
+ attr_accessor :applyNo
5
+ attr_accessor :signatory
6
+
7
+ def initialize options
8
+ self.applyNo = options[:apply_no]
9
+ self.signatory = Junziqian::Model::Signatory.new(options[:signatory]).hash_values
10
+ end
11
+
12
+ def version
13
+ '1.0'
14
+ end
15
+
16
+ def method
17
+ 'sign.status'
18
+ end
19
+
20
+ def ingore_signs
21
+ []
22
+ end
23
+
24
+ def query_params
25
+ {applyNo: applyNo, signatory: signatory}
26
+ end
27
+
28
+
29
+
30
+ def request
31
+ result = Tool::RequestTool.do_post_by_requestObj(self)
32
+ if result['success'] == true
33
+ [result['signStatus'], trans_signstatus(result['signStatus'])]
34
+ else
35
+ result
36
+ end
37
+ end
38
+
39
+ def trans_signstatus status_int
40
+ #1 已签、2 拒签、3 保全
41
+ {1=>'已签', 2=>'拒签', 3=>'保全'}[status_int]
42
+ end
43
+
44
+ def demo
45
+ hash = {signatory: {userType: Junziqian::Cfg::Enum::IDCARD['type'],
46
+ identityType: Junziqian::Cfg::Enum::IDCARD['code'],
47
+ fullName: '张三',
48
+ identityCard: '360732198908110099'},
49
+ apply_no: 'APL882159678413475840'}
50
+ req = Junziqian::Interface::SignStatusRequest.new(hash)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ module Junziqian
2
+ module Model
3
+ class Signatory
4
+ [:userType, :fullName, :identityType, :identityCard, :mobile, :email, :address, :authLeve, :authenticationLevel, :authLevel, :authLevelRange, :forceAuthentication, :signLevel, :forceEvidence, :chapteJson, :noNeedEvidence, :orderNum, :insureYear, :noNeedVerify, :serverCaAuto, :readTime].each do |at|
5
+ attr_accessor at
6
+ end
7
+
8
+
9
+ def initialize options= {}
10
+ options.each do |k, v|
11
+ if self.respond_to?(k)
12
+ self.send("#{k}=", v)
13
+ end
14
+ end
15
+ end
16
+
17
+ def hash_values
18
+ [:userType, :fullName, :identityType, :identityCard, :mobile, :email, :address, :authLeve, :authenticationLevel, :authLevel, :authLevelRange, :forceAuthentication, :signLevel, :forceEvidence, :chapteJson, :noNeedEvidence, :orderNum, :insureYear, :noNeedVerify, :serverCaAuto, :readTime].inject({}) do |hash, item|
19
+ hash[item] = self.send(item)
20
+ hash
21
+ end.to_json
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ require 'base64'
2
+ module Junziqian
3
+ module Tool
4
+ class AttacheUtils
5
+ def initialize file_path
6
+ @file_path = file_path
7
+ end
8
+
9
+ def file_type
10
+ match_data = @file_path.match(/\.([a-z]+)$/)
11
+ match_data ? match_data[1] : ''
12
+ end
13
+
14
+ def value
15
+ @file_path
16
+ end
17
+
18
+ def file_name
19
+ @file_path.match(/([^\/]+\.([a-z]+))$/)[0]
20
+ end
21
+
22
+ def uploadStr
23
+ file =File.open(@file_path)
24
+ b = file.readlines().join('')
25
+ c = Base64.strict_encode64(file_name) +'@'+ Base64.strict_encode64(b)
26
+
27
+ # array('+','/','='),array('-','_','')
28
+ c.gsub('+', '-').gsub('/','_').gsub('=','')
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,43 @@
1
+ require 'digest'
2
+ require 'uri'
3
+ module Junziqian
4
+ module Tool
5
+ class HttpSignUtils
6
+ class << self
7
+ def create_http_url body_params, timestamp = nil
8
+ timestamp ||= get_millisecond
9
+ sign=create_http_sign(body_params, timestamp)
10
+ url='timestamp='+timestamp+'&'; #timestamp必须放在最前面民
11
+ body_params.each do |k, v|
12
+ url += k.to_s + URI::escape(v.strip)
13
+ end
14
+ url += "sign=#{sign}"
15
+ end
16
+
17
+ def get_millisecond
18
+ (Time.now.to_f*1000).to_i.to_s
19
+ end
20
+
21
+ def create_http_sign body_params, timestamp = nil
22
+ timestamp ||= get_millisecond
23
+ contactStr = []
24
+ contactStr << get_params(body_params)
25
+ contactStr << ("timestamp"+timestamp)
26
+ contactStr << ("appKey"+ Cfg::ClientInfo.app_key)
27
+ contactStr << ("appSecret"+ Cfg::ClientInfo.app_secret;)
28
+ Digest::SHA1.hexdigest(contactStr.join(''));
29
+ end
30
+
31
+ def get_params(hash)
32
+ contactStr=[]
33
+ if hash.present?
34
+ hash.sort.map {|array_item|
35
+ contactStr << [array_item[0], array_item[1].strip]
36
+ }
37
+ end
38
+ contactStr.flatten.join('')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,127 @@
1
+ require 'digest'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'mime/types'
6
+
7
+ module Junziqian
8
+ module Tool
9
+ class RequestTool
10
+ CV = '1.1.1'
11
+ BOUNDARY = '00content0boundary00'
12
+ class << self
13
+ def sign(query_params, ignore_params, header_map, ext_info, content_type = 'application/x-www-form-urlencoded; charset=UTF-8')
14
+ #raise '头参数不能为空' if secret.blank? || header_map.blank?
15
+
16
+ contactStr = [Cfg::ClientInfo.app_secret]
17
+ contactStr << contactValues(query_params, ignore_params, content_type)
18
+ contactStr << contactValues(header_map)
19
+ contactStr << contactValues(ext_info)
20
+
21
+ # print contactStr.join('')
22
+ Digest::SHA1.hexdigest(contactStr.join('')).upcase
23
+ end
24
+
25
+ def contactValues(query_params, ignores = [], content_type = 'application/x-www-form-urlencoded; charset=UTF-8')
26
+ contactStr = []
27
+ is_multipart = content_type.downcase.match('multipart/form-data') ? true : false
28
+ unless query_params.empty?
29
+ req_array = query_params.select {|k, v| !ignores.include?(k)}
30
+ req_array.sort.each do |array_item|
31
+ contactStr << array_item[0]
32
+ if array_item[1]
33
+ contactStr << (array_item[1].is_a?(Junziqian::Tool::AttacheUtils) ? array_item[1].value : array_item[1].strip)
34
+ end
35
+ end
36
+ end
37
+ contactStr.join('')
38
+ end
39
+
40
+ def get_heads(method = 'POST', version = '1.0')
41
+ {"ts" => HttpSignUtils.get_millisecond,
42
+ "locale" => "zh_CN",
43
+ "v" => version,
44
+ "method" => method,
45
+ "appKey" => Cfg::ClientInfo.app_key}
46
+ end
47
+
48
+ def get_ext_info
49
+ {'cv' => CV}
50
+ end
51
+
52
+ def encrypt_ext_info ext_hash
53
+ contactStr = []
54
+ if ext_hash
55
+ ext_hash.each do |k, v|
56
+ contactStr << "#{k}\001#{v}\002"
57
+ end
58
+ end
59
+ string = contactStr.join('')
60
+ string == '' ? '' : (string[0, string.length-1].to_s)
61
+ end
62
+
63
+ def create_head_hash(head_map, ext_info, sign, content_type="application/x-www-form-urlencoded; charset=UTF-8")
64
+ hash = {}
65
+ hash['ext'] = encrypt_ext_info(ext_info)
66
+ hash['sign'] = sign
67
+ hash['user-agent'] = 'php'
68
+ hash['Content-type'] = content_type
69
+ hash['accept'] = 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2'
70
+ hash['connection'] = 'keep-alive'
71
+ hash.merge(head_map)
72
+ end
73
+
74
+ def do_post(query_params, ignores_params, head_map, content_type = 'application/x-www-form-urlencoded; charset=UTF-8')
75
+ sign_value = sign(query_params, ignores_params, head_map, get_ext_info,content_type);
76
+ uri = URI.parse(Cfg::ClientInfo.services_url)
77
+ head_hash = create_head_hash(head_map, get_ext_info, sign_value, content_type)
78
+ content = if content_type.match('multipart/form-data')
79
+ head_hash = head_hash.merge({"Content-Type"=> "multipart/form-data, boundary=#{BOUNDARY}"})
80
+ build_form_data(query_params)
81
+ else
82
+ URI.encode_www_form query_params
83
+ end
84
+ head_hash['Content-Length'] = content.length.to_s
85
+ http = Net::HTTP.new(uri.host, uri.port)
86
+ response = http.post(uri.path, content, head_hash)
87
+ return JSON.parse(response.body)
88
+ end
89
+
90
+ def do_post_by_requestObj( requestObj)
91
+ # hash = hash.serialize_keys
92
+ headerMap = get_heads(requestObj.method, requestObj.version)
93
+ query_params = requestObj.query_params
94
+ do_post(query_params, requestObj.ignores_params, headerMap, requestObj.content_type)
95
+ end
96
+
97
+
98
+ def build_form_data(query_params, boundary = BOUNDARY)
99
+ body = []
100
+ query_params.each do |k, v|
101
+ if v.present?
102
+ body << "--"+ boundary + "\r\n"
103
+ body << "Content-Disposition: form-data; name=\"#{k}\"\r\n\r\n";
104
+ if v.is_a?(Junziqian::Tool::AttacheUtils)
105
+ body << v.uploadStr+"\r\n";
106
+ else
107
+ body << "#{v}\r\n";
108
+ end
109
+ end
110
+ end
111
+ if body.size > 0
112
+ body << "--"+ boundary + "--\r\n";
113
+ end
114
+ body.join('')
115
+ end
116
+
117
+ def create_http_sign body_hash, timestamp
118
+ array = [contactValues(body_hash)]
119
+ array << "timestamp#{timestamp}"
120
+ array << "appKey#{Junziqian::Cfg::ClientInfo.app_key}"
121
+ array << "appSecret#{Junziqian::Cfg::ClientInfo.app_secret}"
122
+ Digest::SHA1.hexdigest(array.join(''))
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,3 @@
1
+ module Junziqian
2
+ VERSION = "0.1.1"
3
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: junziqian
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - 方峦
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-11 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: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: ruby版本的支持君子签,电子签名的gem库
56
+ email:
57
+ - moonless@fangluandeMacBook-Pro.local
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".ruby-version"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - junziqian.gemspec
71
+ - lib/junziqian.rb
72
+ - lib/junziqian/cfg/client_info.rb
73
+ - lib/junziqian/cfg/enum.rb
74
+ - lib/junziqian/interface/apply_sign_file_request.rb
75
+ - lib/junziqian/interface/base_request.rb
76
+ - lib/junziqian/interface/detail_anony_link_request.rb
77
+ - lib/junziqian/interface/file_link_request.rb
78
+ - lib/junziqian/interface/ping.rb
79
+ - lib/junziqian/interface/pres_file_link.rb
80
+ - lib/junziqian/interface/sign_status_request.rb
81
+ - lib/junziqian/model/signatory.rb
82
+ - lib/junziqian/tool/attache_utils.rb
83
+ - lib/junziqian/tool/http_sign_utils.rb
84
+ - lib/junziqian/tool/request_tool.rb
85
+ - lib/junziqian/version.rb
86
+ homepage: http://github.com/orichi/junziqian
87
+ licenses: []
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.6.10
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: 支持君子签,电子签名
109
+ test_files: []