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 +4 -4
- data/app/controllers/weixin_rails_middleware/weixin_controller.rb +5 -5
- data/config/routes.rb +2 -2
- data/lib/generators/templates/add_weixin_secret_key_and_weixin_token_migration.rb +16 -0
- data/lib/generators/templates/install_weixin_rails_middleware.rb +23 -0
- data/lib/generators/weixin_rails_middleware/install_generator.rb +3 -3
- data/lib/generators/weixin_rails_middleware/migration_generator.rb +15 -0
- data/lib/weixin_rails_middleware.rb +1 -15
- data/lib/weixin_rails_middleware/configuration.rb +28 -13
- data/lib/weixin_rails_middleware/engine.rb +18 -0
- data/lib/weixin_rails_middleware/helpers/weixin_authorize_helper.rb +20 -15
- data/lib/weixin_rails_middleware/version.rb +1 -1
- metadata +7 -6
- data/lib/generators/templates/initializer.rb +0 -22
- data/lib/weixin_rails_middleware/helpers/weixin_token_form_helper.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c106f4f5b4f9a69155ebed8496650fea9e818c5e
|
4
|
+
data.tar.gz: 5e14b1dcb4fb846396a93d2e243fd1591310f645
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
8
|
-
|
9
|
-
|
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
|
24
|
-
@weixin_public_account ||=
|
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/:
|
3
|
-
post 'weixin/:
|
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
|
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 '
|
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 '
|
4
|
-
# use '
|
5
|
-
attr_accessor :
|
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
|
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
|
22
|
-
@
|
36
|
+
def weixin_token_string
|
37
|
+
@weixin_token_string ||= WeixinRailsMiddleware.config.weixin_token_string.to_s
|
23
38
|
end
|
24
39
|
|
25
|
-
def
|
26
|
-
@
|
40
|
+
def token_model
|
41
|
+
@public_account_class ||= WeixinRailsMiddleware.config.public_account_class
|
27
42
|
end
|
28
43
|
|
29
|
-
def
|
30
|
-
@
|
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 `
|
54
|
+
raise "You need to config `public_account_class` in 'config/initializers/weixin_rails_middleware.rb'"
|
40
55
|
end
|
41
|
-
@
|
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
|
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
|
15
|
-
if
|
16
|
-
if
|
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
|
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
|
30
|
-
signature
|
31
|
-
timestamp
|
32
|
-
nonce
|
33
|
-
|
34
|
-
|
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
|
-
|
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
|
43
|
-
|
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
|
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
|
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-
|
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.
|
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.
|
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/
|
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
|