qy_wechat 1.0.0.beta1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: