qy_wechat 1.0.0.beta1 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0406f31fb56e074f7cf19633c0430a2a13dbedd
4
- data.tar.gz: 44e9e8ae54ef833ab1ba3ba9c72ddb1f07d56d1b
3
+ metadata.gz: 505125c4235efd523f2774164afcc1c7b7521fc9
4
+ data.tar.gz: f2dc205a51ea586bc357e90f3df2a7c5bee7b444
5
5
  SHA512:
6
- metadata.gz: 1e1f81653a492b0b5d755a7e3b1e548e95313a38232568e4725127ac4c3ea395fae18d9c8f1b18cecc6c8580562376dabb77b70c4a4e007a6d8345f9a1f7fb3d
7
- data.tar.gz: e95dddb6e3f94d51cd24cb086fdc6f7c1db1a8e8a199ad58291805752729e44b69a44bfd312be5de43e8b8bb6a5be55e5bee0368ee0c1852510bb2479ac4d5e8
6
+ metadata.gz: 51c856d400d5bdd48e2a62a34f889837ccfb401fba7b27c52f9c177bd128cefa2e60dd87c485431d3284fce9eb4453a943a992b400aa20cc53804ec715132be6
7
+ data.tar.gz: 71d41f3170e57de76cab0d64a63dff263850e9688b66b5fff27adf06946a47e24b041b5a874b8ff6a57b352dcd7efafb7345fb13942fd5f7c0d3868402f7c1cf
@@ -5,15 +5,19 @@ module QyWechat
5
5
  include ReplyMessageHelper
6
6
 
7
7
  skip_before_filter :verify_authenticity_token, only: :reply
8
- before_action :setup_qy_account, only: [:verify_url, :reply]
9
- before_action :setup_wechat_message, only: :reply
8
+ before_filter :setup_qy_app, only: [:verify_url, :reply]
9
+ before_filter :setup_wechat_message, only: :reply
10
10
 
11
11
  # 验证URL有效性
12
+ # TODO: refactor
12
13
  def verify_url
13
- raise "Not Match" if not valid_msg_signature(params)
14
- params.delete(:qy_secret_key)
15
- content = Prpcrypt.decrypt(aes_key, params[:echostr], corp_id)
16
- render text: content
14
+ if not valid_msg_signature(params)
15
+ Rails.logger.debug("#{__FILE__}:#{__LINE__} Failure because signature is invalid")
16
+ render text: "", status: 401
17
+ return
18
+ end
19
+ content, status = Prpcrypt.decrypt(aes_key, params[:echostr], corp_id)
20
+ render text: content, status: status
17
21
  end
18
22
 
19
23
  def reply;end
@@ -21,31 +25,33 @@ module QyWechat
21
25
  private
22
26
 
23
27
  def setup_wechat_message
24
- param_xml = request.body.read
25
- hash = MultiXml.parse(param_xml)['xml']
26
- @body_xml = OpenStruct.new(hash)
27
- hash = MultiXml.parse(Prpcrypt.decrypt(aes_key, @body_xml.Encrypt, corp_id))["xml"]
28
+ param_xml = request.body.read
29
+ hash = MultiXml.parse(param_xml)['xml']
30
+ @body_xml = OpenStruct.new(hash)
31
+ content = Prpcrypt.decrypt(aes_key, @body_xml.Encrypt, corp_id)[0]
32
+ hash = MultiXml.parse(content)["xml"]
28
33
  @weixin_message = Message.factory(hash)
29
- @keyword = @weixin_message.Content
34
+ @keyword = @weixin_message.Content
30
35
  end
31
36
 
32
37
  def encoding_aes_key
33
- @qy_account.encoding_aes_key
38
+ key = @qy_app.encoding_aes_key
39
+ raise "长度固定为43个字符" if key.length != 43
40
+ key
34
41
  end
35
42
 
36
43
  def qy_token
37
- @qy_account.qy_token
44
+ @qy_app.qy_token
38
45
  end
39
46
 
40
47
  def aes_key
41
- Base64.decode64(@qy_account.encoding_aes_key + "=")
48
+ Base64.decode64(@qy_app.encoding_aes_key + "=")
42
49
  end
43
50
 
44
51
  def corp_id
45
- @qy_account.corp_id
52
+ @qy_app.corp_id
46
53
  end
47
54
 
48
- # String signature = SHA1.getSHA1(token, timeStamp, nonce, echoStr);
49
55
  def valid_msg_signature(params)
50
56
  timestamp = params[:timestamp]
51
57
  nonce = params[:nonce]
@@ -53,12 +59,13 @@ module QyWechat
53
59
  msg_signature = params[:msg_signature]
54
60
  sort_params = [qy_token, timestamp, nonce, echo_str].sort.join
55
61
  current_signature = Digest::SHA1.hexdigest(sort_params)
56
- Rails.logger.info("current_signature: #{current_signature} " )
62
+ Rails.logger.info("current_signature: #{current_signature} ")
57
63
  current_signature == msg_signature
58
64
  end
59
65
 
60
- def setup_qy_account
61
- @qy_account ||= QyWechat.qy_model.find_by(qy_secret_key: params[:qy_secret_key])
66
+ def setup_qy_app
67
+ qy_secret_key = params.delete(:qy_secret_key)
68
+ @qy_app ||= QyWechat.qy_model.find_by_qy_secret_key!(qy_secret_key: qy_secret_key)
62
69
  end
63
70
  end
64
71
  end
@@ -1,6 +1,6 @@
1
1
  class AddQyWechatColumnsTo<%= table_name.camelize %> < ActiveRecord::Migration
2
2
  def self.up
3
- create_table(:<%= table_name %>) do |t|
3
+ change_table(:<%= table_name %>) do |t|
4
4
  t.string :qy_token
5
5
  t.string :encoding_aes_key
6
6
  t.string :corp_id
@@ -1,4 +1,7 @@
1
+ # encoding: utf-8
2
+
1
3
  QyWechat.configure do |config|
2
- # 配置保存你企业信息的Model
3
- # config.qy_account = "QyAccount"
4
+ # 配置保存你企业应用的Model
5
+ # 特别注意: 由于一个企业号,可以对应多个应用,可以根据 `corp_id` 关联到企业号应用Model。
6
+ # config.qy_app = "QyApp"
4
7
  end
@@ -27,4 +27,9 @@ QyWechat::QyWechatController.class_eval do
27
27
  generate_video_message(new_video(@weixin_message.MediaId, "desc", "title"))
28
28
  end
29
29
 
30
+ # 用于响应事件
31
+ def response_event_message
32
+ generate_text_message("响应事件")
33
+ end
34
+
30
35
  end
@@ -13,12 +13,12 @@ module QyWechat
13
13
  end
14
14
 
15
15
  def qy_model_name
16
- @qy_model_name ||= QyWechat.config.qy_account
16
+ @qy_model_name ||= QyWechat.config.qy_app
17
17
  end
18
18
 
19
19
  def qy_model
20
20
  if qy_model_name.blank?
21
- raise "You need to config `qy_account` in 'config/initializers/qy_wechat_config.rb'"
21
+ raise "You need to config `qy_app` in 'config/initializers/qy_wechat_config.rb'"
22
22
  end
23
23
  @qy_model ||= qy_model_name.to_s.constantize
24
24
  end
@@ -26,6 +26,6 @@ module QyWechat
26
26
  end
27
27
 
28
28
  class Configuration
29
- attr_accessor :qy_account
29
+ attr_accessor :qy_app
30
30
  end
31
31
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module QyWechat
2
4
  module PKCS7Encoder
3
5
  extend self
@@ -6,16 +6,21 @@ module QyWechat
6
6
  # 对密文进行解密.
7
7
  # text 需要解密的密文
8
8
  def decrypt(aes_key, text, corpid)
9
- text = Base64.decode64(text)
10
- text = handle_cipher(:decrypt, aes_key, text)
11
- result = PKCS7Encoder.decode(text)
12
- content = result[16...result.length]
13
- len_list = content[0...4].unpack("N")
14
- xml_len = len_list[0]
15
- xml_content = content[4...4 + xml_len]
9
+ status = 200
10
+ text = Base64.decode64(text)
11
+ text = handle_cipher(:decrypt, aes_key, text)
12
+ result = PKCS7Encoder.decode(text)
13
+ content = result[16...result.length]
14
+ len_list = content[0...4].unpack("N")
15
+ xml_len = len_list[0]
16
+ xml_content = content[4...4 + xml_len]
16
17
  from_corpid = content[xml_len+4...content.size]
17
- raise "UnMatch corpid" if corpid != from_corpid
18
- xml_content
18
+ # TODO: refactor
19
+ if corpid != from_corpid
20
+ Rails.logger.debug("#{__FILE__}:#{__LINE__} Failure because corpid != from_corpid")
21
+ status = 401
22
+ end
23
+ [xml_content, status]
19
24
  end
20
25
 
21
26
  # 加密
@@ -1,9 +1,8 @@
1
+ # encoding: utf-8
2
+
1
3
  module QyWechat
2
4
  module ReplyMessageHelper
3
5
 
4
- # e.g.
5
- # generate_text_message(@weixin_message.ToUserName, @weixin_message.FromUserName, "Your Message: #{@weixin_message.Content}")
6
- # Or generate_text_message("Your Message: #{@weixin_message.Content}")
7
6
  def generate_text_message(from=nil, to=nil, content)
8
7
  message = TextResponseMessage.new
9
8
  message.FromUserName = from || @weixin_message.ToUserName
@@ -21,7 +20,6 @@ module QyWechat
21
20
  item
22
21
  end
23
22
 
24
- # articles = [new_article]
25
23
  def generate_news_message(from=nil, to=nil, articles)
26
24
  message = NewsResponseMessage.new
27
25
  message.FromUserName = from || @weixin_message.ToUserName
@@ -39,18 +37,6 @@ module QyWechat
39
37
  video
40
38
  end
41
39
 
42
- # <xml>
43
- # <ToUserName><![CDATA[toUser]]></ToUserName>
44
- # <FromUserName><![CDATA[fromUser]]></FromUserName>
45
- # <CreateTime>12345678</CreateTime>
46
- # <MsgType><![CDATA[video]]></MsgType>
47
- # <Video>
48
- # <MediaId><![CDATA[media_id]]></MediaId>
49
- # <Title><![CDATA[title]]></Title>
50
- # <Description><![CDATA[description]]></Description>
51
- # </Video>
52
- # </xml>
53
-
54
40
  def generate_video_message(from=nil, to=nil, video)
55
41
  message = VideoResponseMessage.new
56
42
  message.FromUserName = from || @weixin_message.ToUserName
@@ -100,14 +86,13 @@ module QyWechat
100
86
  msg = EncryptMessage.new
101
87
  msg.Encrypt = encrypt_xml
102
88
  msg.TimeStamp = Time.now.to_i.to_s
103
- msg.Nonce = "123"
89
+ msg.Nonce = SecureRandom.hex(8)
104
90
  msg.MsgSignature = generate_msg_signature(encrypt_xml, msg)
105
91
  msg.to_xml
106
92
  end
107
93
 
108
94
  # dev_msg_signature=sha1(sort(token、timestamp、nonce、msg_encrypt))
109
95
  # 生成企业签名
110
- # $array = array($encrypt_msg, $token, $timestamp, $nonce);
111
96
  def generate_msg_signature(encrypt_msg, msg)
112
97
  sort_params = [encrypt_msg, qy_token, msg.TimeStamp, msg.Nonce].sort.join
113
98
  Digest::SHA1.hexdigest(sort_params)
@@ -1,10 +1,5 @@
1
1
  # encoding: utf-8
2
- # ref: https://github.com/wolfg1969/rack-weixin/lib/weixin/model.rb
3
- require 'roxml'
4
- require 'multi_xml'
5
- require 'ostruct'
6
2
 
7
- # multi_xml will use Nokogiri if it is available
8
3
  MultiXml.parser = :nokogiri
9
4
 
10
5
  module QyWechat
@@ -1,6 +1,4 @@
1
1
  # encoding: utf-8
2
- # ref: https://github.com/wolfg1969/rack-weixin/lib/weixin/model.rb
3
- require 'roxml'
4
2
 
5
3
  module QyWechat
6
4
 
@@ -1,3 +1,3 @@
1
1
  module QyWechat
2
- VERSION = "1.0.0.beta1"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qy_wechat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - lanrion
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-04 00:00:00.000000000 Z
11
+ date: 2014-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: "微信企业版本,应答API集成"
83
+ description: Ruby on Rails 微信企业版本,应答API集成
84
84
  email:
85
85
  - huaitao-deng@foxmail.com
86
86
  executables: []
@@ -121,14 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
121
  version: '0'
122
122
  required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  requirements:
124
- - - ">"
124
+ - - ">="
125
125
  - !ruby/object:Gem::Version
126
- version: 1.3.1
126
+ version: '0'
127
127
  requirements: []
128
128
  rubyforge_project:
129
129
  rubygems_version: 2.2.2
130
130
  signing_key:
131
131
  specification_version: 4
132
- summary: "微信企业版本"
132
+ summary: Ruby on Rails 微信企业版本
133
133
  test_files: []
134
134
  has_rdoc: