weixin_rails_middleware 1.0.5 → 1.1.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: 7f65d96d4e58350a83ec0fba14b711b4250e79c3
4
- data.tar.gz: 21999d40da51005a1ad025473a6fd987a3e77af5
3
+ metadata.gz: c106f4f5b4f9a69155ebed8496650fea9e818c5e
4
+ data.tar.gz: 5e14b1dcb4fb846396a93d2e243fd1591310f645
5
5
  SHA512:
6
- metadata.gz: f7178de0133a47bf05e75c1bbc9d11bcab4a1b9b86b5bfad3cecb255f206c7b6638d5c2daa5dd09edae8bf1bb8fcda83068b91bb9ac126e6464a937f82b37ef6
7
- data.tar.gz: 20d4da31eb5d6fce51b72f40bd7ce1ffc672d1e82c4d408efdd2f574091a1fda836239e39b2692546bcae5d5bdcbf817b05e2b821c14de83ca2919335898da06
6
+ metadata.gz: 7cf5f89774e7659dffe2b12be128348b0fb34e12afd73cf9cb9db80c230ced3996ec37033cd62a492969f727aefed648a29b86be905043f0237cddac07adf349
7
+ data.tar.gz: 140ce490d0704183158f44112cb2cb9460a99628a0e462507ae820cefc49ac4c95794b45f50a12a58d0a2820f01c7a4422c44e179af19fb094bd5aae361fd49c
@@ -4,9 +4,9 @@ module WeixinRailsMiddleware
4
4
  include ConfigurationHelpers
5
5
  include WeixinAuthorizeHelper
6
6
 
7
- skip_before_action :verify_authenticity_token
8
- before_action :check_weixin_params, only: [:index, :reply]
9
- before_action :set_weixin_public_account, :set_weixin_message, only: :reply
7
+ skip_before_filter :verify_authenticity_token
8
+ before_filter :check_weixin_params, only: [:index, :reply]
9
+ before_filter :set_weixin_public_account, :set_weixin_message, only: :reply
10
10
 
11
11
  def index
12
12
  render text: params[:echostr]
@@ -20,8 +20,8 @@ module WeixinRailsMiddleware
20
20
  ## Callback
21
21
  # e.g. will generate +@weixin_public_account+
22
22
  def set_weixin_public_account
23
- return nil if token_string.present?
24
- @weixin_public_account ||= token_model_instance
23
+ return nil if weixin_token_string.present?
24
+ @weixin_public_account ||= current_weixin_public_account
25
25
  end
26
26
 
27
27
  def set_weixin_message
data/config/routes.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  WeixinRailsMiddleware::Engine.routes.draw do
2
- get 'weixin/:weixin_token', to: 'weixin#index', as: :weixin_index
3
- post 'weixin/:weixin_token', to: 'weixin#reply', as: :weixin_reply
2
+ get 'weixin/:weixin_secret_key', to: 'weixin#index', as: :weixin_index
3
+ post 'weixin/:weixin_secret_key', to: 'weixin#reply', as: :weixin_reply
4
4
  end
@@ -0,0 +1,16 @@
1
+ class AddWeixinSecretKeyAndWeixinTokenTo<%= table_name.camelize %> < ActiveRecord::Migration
2
+ def self.up
3
+ change_table(:<%= table_name %>) do |t|
4
+ t.string :weixin_secret_key
5
+ t.string :weixin_token
6
+ end
7
+ add_index :<%= table_name %>, :weixin_secret_key
8
+ add_index :<%= table_name %>, :weixin_token
9
+ end
10
+
11
+ def self.down
12
+ # By default, we don't want to make any assumption about how to roll back a migration when your
13
+ # model already existed. Please edit below which fields you would like to remove in this migration.
14
+ raise ActiveRecord::IrreversibleMigration
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ # Use this hook to configure WeixinRailsMiddleware bahaviors.
2
+ WeixinRailsMiddleware.configure do |config|
3
+
4
+ ## NOTE:
5
+ ## If you config all them, it will use `weixin_token_string` default
6
+
7
+ ## Config public_account_class if you SAVE public_account into database ##
8
+ # Th first configure is fit for your weixin public_account is saved in database.
9
+ # +public_account_class+ The class name that to save your public_account
10
+ # config.public_account_class = ""
11
+
12
+ ## Here configure is for you DON'T WANT TO SAVE your public account into database ##
13
+ # Or the other configure is fit for only one weixin public_account
14
+ # If you config `weixin_token_string`, so it will directly use it
15
+ # config.weixin_token_string = '<%= SecureRandom.hex(12) %>'
16
+ # using to weixin server url to validate the token can be trusted.
17
+ # config.weixin_secret_string = '<%= WeiXinUniqueToken.generate(generator: :urlsafe_base64, size: 24) %>'
18
+
19
+ ## Router configure ##
20
+ # Default is "/", and recommend you use default directly.
21
+ # config.engine_path = "/"
22
+
23
+ end
@@ -5,14 +5,14 @@ module WeixinRailsMiddleware
5
5
  class InstallGenerator < Rails::Generators::Base
6
6
  source_root File.expand_path('../../templates', __FILE__)
7
7
 
8
- desc 'Creates a Dashing initializer for your application.'
8
+ desc 'Creates a WeixinRailsMiddleware initializer for your application.'
9
9
 
10
10
  def install
11
11
  route 'mount WeixinRailsMiddleware::Engine, at: WeixinRailsMiddleware.config.engine_path'
12
12
  end
13
13
 
14
14
  def copy_initializer
15
- template 'initializer.rb', 'config/initializers/weixin_rails_middleware.rb'
15
+ template 'install_weixin_rails_middleware.rb', 'config/initializers/weixin_rails_middleware.rb'
16
16
  end
17
17
 
18
18
  def configure_application
@@ -32,4 +32,4 @@ module WeixinRailsMiddleware
32
32
 
33
33
  end
34
34
  end
35
- end
35
+ end
@@ -0,0 +1,15 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module WeixinRailsMiddleware
4
+ module Generators
5
+ class MigrationGenerator < ActiveRecord::Generators::Base
6
+ source_root File.expand_path('../../templates', __FILE__)
7
+
8
+ desc 'Adds a Wexin Secret Key for your application.'
9
+ def create_migration_file
10
+ migration_template "add_weixin_secret_key_and_weixin_token_migration.rb", "db/migrate/add_weixin_secret_key_and_weixin_token_to_#{plural_name}.rb"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -3,7 +3,6 @@ require "weixin_rails_middleware/engine"
3
3
  require "weixin_rails_middleware/models/message"
4
4
  require "weixin_rails_middleware/models/reply_message"
5
5
  require "weixin_rails_middleware/helpers/reply_weixin_message_helper"
6
- require "weixin_rails_middleware/helpers/weixin_token_form_helper"
7
6
  require "weixin_rails_middleware/helpers/unique_token_helper"
8
7
  require "weixin_rails_middleware/helpers/weixin_authorize_helper"
9
8
 
@@ -11,20 +10,7 @@ module WeixinRailsMiddleware
11
10
 
12
11
  DEFAULT_TOKEN_COLUMN_NAME = "weixin_token".freeze
13
12
  DEFAULT_ENGINE_PATH = "/".freeze
14
-
15
- class << self
16
-
17
- attr_accessor :configuration
18
-
19
- def config
20
- self.configuration ||= Configuration.new
21
- end
22
-
23
- def configure
24
- yield config if block_given?
25
- end
26
-
27
- end
13
+ DEFAULT_WEIXIN_SECRET_KEY = "weixin_secret_key".freeze
28
14
 
29
15
  end
30
16
 
@@ -1,12 +1,27 @@
1
1
  module WeixinRailsMiddleware
2
+
3
+ class << self
4
+
5
+ attr_accessor :configuration
6
+
7
+ def config
8
+ self.configuration ||= Configuration.new
9
+ end
10
+
11
+ def configure
12
+ yield config if block_given?
13
+ end
14
+
15
+ end
16
+
2
17
  class Configuration
3
- # use 'token_model': if the token is saved in SomeModel, then find token by it
4
- # use 'token_string': if the token is a String, just use it,
5
- attr_accessor :token_model, :token_column, :token_string, :engine_path
18
+ # use 'public_account_class': if the token is saved in SomeModel, then find token by it
19
+ # use 'weixin_token': if the token is a String, just use it,
20
+ attr_accessor :public_account_class, :weixin_token_string, :weixin_secret_string
21
+ attr_accessor :engine_path
6
22
 
7
23
  def initialize
8
- @engine_path = DEFAULT_ENGINE_PATH
9
- @token_column = DEFAULT_TOKEN_COLUMN_NAME
24
+ @engine_path = DEFAULT_ENGINE_PATH
10
25
  end
11
26
 
12
27
  end
@@ -18,16 +33,16 @@ module WeixinRailsMiddleware
18
33
  @engine_path ||= WeixinRailsMiddleware.config.engine_path
19
34
  end
20
35
 
21
- def token_string
22
- @token_string ||= WeixinRailsMiddleware.config.token_string.to_s
36
+ def weixin_token_string
37
+ @weixin_token_string ||= WeixinRailsMiddleware.config.weixin_token_string.to_s
23
38
  end
24
39
 
25
- def token_column
26
- @token_column ||= WeixinRailsMiddleware.config.token_column
40
+ def token_model
41
+ @public_account_class ||= WeixinRailsMiddleware.config.public_account_class
27
42
  end
28
43
 
29
- def token_model
30
- @token_model ||= WeixinRailsMiddleware.config.token_model
44
+ def weixin_secret_string
45
+ @weixin_secret_string ||= WeixinRailsMiddleware.config.weixin_secret_string.to_s
31
46
  end
32
47
 
33
48
  def is_default_engine_path?
@@ -36,9 +51,9 @@ module WeixinRailsMiddleware
36
51
 
37
52
  def token_model_class
38
53
  if token_model.blank?
39
- raise "You need to config `token_model` in 'config/initializers/weixin_rails_middleware.rb'"
54
+ raise "You need to config `public_account_class` in 'config/initializers/weixin_rails_middleware.rb'"
40
55
  end
41
- @token_model_c ||= token_model.constantize
56
+ @token_model_class_name ||= token_model.constantize
42
57
  end
43
58
  end
44
59
  end
@@ -1,7 +1,25 @@
1
1
  module WeixinRailsMiddleware
2
2
  class Engine < ::Rails::Engine
3
+ include ConfigurationHelpers
4
+
3
5
  isolate_namespace WeixinRailsMiddleware
4
6
  engine_name :weixin_engine
5
7
 
8
+ config.after_initialize do
9
+ token_model_callback if token_model.present?
10
+ end
11
+
12
+ private
13
+
14
+ def token_model_callback
15
+ token_model_class.class_eval do
16
+ before_create do
17
+ # TODO: refactor
18
+ self.weixin_secret_key = WeiXinUniqueToken.generate(generator: :urlsafe_base64, size: 24) if weixin_secret_key.blank?
19
+ self.weixin_token = WeiXinUniqueToken.generate if weixin_token.blank?
20
+ end
21
+ end
22
+ end
23
+
6
24
  end
7
25
  end
@@ -5,20 +5,20 @@ module WeixinRailsMiddleware
5
5
  protected
6
6
 
7
7
  def check_weixin_params
8
- if check_weixin_token_valid? && !is_hexdigest?
8
+ if is_weixin_secret_key_valid? && is_signature_invalid?
9
9
  render text: "Forbidden", status: 403
10
10
  end
11
11
  end
12
12
 
13
13
  # check the token from Weixin Service is exist in local store.
14
- def check_weixin_token_valid?
15
- if token_string.blank?
16
- if token_model_instance.blank?
14
+ def is_weixin_secret_key_valid?
15
+ if weixin_token_string.blank?
16
+ if current_weixin_public_account.blank?
17
17
  render text: "Forbidden", status: 403
18
18
  return false
19
19
  end
20
20
  else
21
- if current_weixin_token != token_string
21
+ if current_weixin_secret_key != weixin_secret_string
22
22
  render text: "Forbidden", status: 403
23
23
  return false
24
24
  end
@@ -26,22 +26,27 @@ module WeixinRailsMiddleware
26
26
  true
27
27
  end
28
28
 
29
- def is_hexdigest?
30
- signature = params[:signature] || ''
31
- timestamp = params[:timestamp] || ''
32
- nonce = params[:nonce] || ''
33
- current_signature = Digest::SHA1.hexdigest([current_weixin_token, timestamp, nonce].sort.join)
34
- return true if current_signature == signature
29
+ def is_signature_invalid?
30
+ signature = params[:signature] || ''
31
+ timestamp = params[:timestamp] || ''
32
+ nonce = params[:nonce] || ''
33
+ sort_params = [current_weixin_token, timestamp, nonce].sort.join
34
+ current_signature = Digest::SHA1.hexdigest(sort_params)
35
+ return true if current_signature != signature
35
36
  false
36
37
  end
37
38
 
39
+ def current_weixin_secret_key
40
+ @weixin_secret_key = params[:weixin_secret_key]
41
+ end
42
+
38
43
  def current_weixin_token
39
- @weixin_token = params[:weixin_token]
44
+ return weixin_token_string if weixin_token_string.present?
45
+ current_weixin_public_account.try(DEFAULT_TOKEN_COLUMN_NAME)
40
46
  end
41
47
 
42
- def token_model_instance
43
- token_model_instance = token_model_class.where("#{token_column}" => current_weixin_token).first
44
- token_model_instance
48
+ def current_weixin_public_account
49
+ @current_weixin_public_account = token_model_class.where("#{DEFAULT_WEIXIN_SECRET_KEY}" => current_weixin_secret_key).first
45
50
  end
46
51
 
47
52
  # return a message class with current_weixin_params
@@ -1,3 +1,3 @@
1
1
  module WeixinRailsMiddleware
2
- VERSION = "1.0.5".freeze
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weixin_rails_middleware
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.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-03-19 00:00:00.000000000 Z
11
+ date: 2014-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - '>='
60
60
  - !ruby/object:Gem::Version
61
- version: 1.7.9
61
+ version: 1.9.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
- version: 1.7.9
68
+ version: 1.9.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: multi_xml
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -105,9 +105,11 @@ files:
105
105
  - Rakefile
106
106
  - app/controllers/weixin_rails_middleware/weixin_controller.rb
107
107
  - config/routes.rb
108
- - lib/generators/templates/initializer.rb
108
+ - lib/generators/templates/add_weixin_secret_key_and_weixin_token_migration.rb
109
+ - lib/generators/templates/install_weixin_rails_middleware.rb
109
110
  - lib/generators/templates/weixin_controller.rb
110
111
  - lib/generators/weixin_rails_middleware/install_generator.rb
112
+ - lib/generators/weixin_rails_middleware/migration_generator.rb
111
113
  - lib/tasks/weixin_rails_middleware_tasks.rake
112
114
  - lib/weixin_rails_middleware.rb
113
115
  - lib/weixin_rails_middleware/configuration.rb
@@ -115,7 +117,6 @@ files:
115
117
  - lib/weixin_rails_middleware/helpers/reply_weixin_message_helper.rb
116
118
  - lib/weixin_rails_middleware/helpers/unique_token_helper.rb
117
119
  - lib/weixin_rails_middleware/helpers/weixin_authorize_helper.rb
118
- - lib/weixin_rails_middleware/helpers/weixin_token_form_helper.rb
119
120
  - lib/weixin_rails_middleware/models/message.rb
120
121
  - lib/weixin_rails_middleware/models/reply_message.rb
121
122
  - lib/weixin_rails_middleware/version.rb
@@ -1,22 +0,0 @@
1
- # Use this hook to configure WeixinRailsMiddleware bahaviors.
2
- WeixinRailsMiddleware.configure do |config|
3
-
4
- ## NOTE:
5
- ## If you config all them, it will use `token_string` default
6
- ##
7
- # Th first configure is fit for your weixin public_account is saved in database.
8
- # +token_model+ and +token_column+ must in the same table.
9
- # +token_model+ The class name that to save your public_account
10
- # +token_column+ You can config a column name Optional, but you must have a column `weixin_token` default.
11
- # config.token_model = ""
12
- # config.token_column = "weixin_token"
13
-
14
- # Or the other configure is fit for only one weixin public_account
15
- # If you config `token_string`, so it will directly use it
16
- # config.token_string = "token string"
17
-
18
- # Router
19
- # Default is "/", and recommend you use default directly.
20
- # config.engine_path = "/"
21
-
22
- end
@@ -1,43 +0,0 @@
1
- # custom weixin_token_field
2
- # usage: +f.weixin_token_field: weixin_token+
3
- module ActionView
4
- module Helpers
5
- module Tags # :nodoc:
6
- class WeixinTokenField < TextField # :nodoc:
7
- def render
8
- # custom weixin_token value
9
- @options["type"]="text"
10
- @options = {value: generate_weixin_token }.merge!(@options)
11
- super
12
- end
13
-
14
- private
15
-
16
- def generate_weixin_token
17
- @options.fetch("value"){value_before_type_cast(object)} || WeiXinUniqueToken.generate
18
- end
19
- end
20
- end # end of Tags
21
-
22
- module FormHelper
23
- extend ActiveSupport::Concern
24
- def weixin_token_field(object_name, method, options = {})
25
- Tags::WeixinTokenField.new(object_name, method, self, options).render
26
- end
27
- end # end of FormHelper
28
-
29
- class FormBuilder
30
- selector = :weixin_token_field
31
- class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
32
- def #{selector}(method, options = {}) # def text_field(method, options = {})
33
- @template.send( # @template.send(
34
- #{selector.inspect}, # "text_field",
35
- @object_name, # @object_name,
36
- method, # method,
37
- objectify_options(options)) # objectify_options(options))
38
- end # end
39
- RUBY_EVAL
40
- end # end of FormHelper
41
-
42
- end # HELPERS
43
- end