junziqian 0.1.1

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
+ 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: []