weixin_rails_middleware 1.0.5 → 1.1.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: 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