weixin_authorize 1.5.5 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9c7e75ae1a9b81d02ddaba6cf28d0ef9afe64a7c
4
- data.tar.gz: 5aeca7b27d5a5a81c780c406ab520bff27835871
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWIzYzY2N2NmMTJjYmZmOThjZDQ1ZmZkMDVlZmVjOGIxNDYwNjgyOQ==
5
+ data.tar.gz: !binary |-
6
+ OTNkNzc1MmNjY2I1MGZlNjE0YmI0ZTZhZDc4ZTZiMDZlNzcwM2U3Yw==
5
7
  SHA512:
6
- metadata.gz: 18949cdd4dc1d47ca7123da41290422c6bc65a8ec5aa50556f890c657ddc525fa5970e222b50acea27e358c493e0558f05e8c84e254a779f94f3f8c70d7ddd7f
7
- data.tar.gz: dd6135a09e0e930e441dfc886303c5d83e33129e105719c51a79927a264ba9a86c619b4599cb6ca45987b7696e2d8ad60221c6aa267f5dc3999750640f34a27c
8
+ metadata.gz: !binary |-
9
+ N2ZlNTJmMWQxNDFlZDMzYzQ1MDhhNDE4ZDU5OGUwM2E0ZDRkNjg3YmMwMTVm
10
+ OWE1MDlhMzg4MzBjMDMzNDY2NmNkMDUwYjlkMDM1MjVmNjc2YjdkOTlhZmQz
11
+ ODZmZTE1YjY1YjFiNDg4MTk4MzRlYTg2MGJlYjg5ZTFlY2E5NDk=
12
+ data.tar.gz: !binary |-
13
+ ZDg4MjkwYzRhODM0YWYxYWE4NjI4MzhhOWMyNWMzZDQ2ZTdlOTllMjFhZDFl
14
+ NGI3NjAwYmQzYTI5ZTlhM2Y0MmRkYmNkMjRjN2M5ODNhMGQ5MjNkOTI1NGQ3
15
+ NjRmZWQyMTQxYjZlYWMyYTJlZjNlYWZjMWM1OTc5ZDMxODVkNDQ=
data/Gemfile CHANGED
@@ -2,10 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in weixin_authorize.gemspec
4
4
  gemspec
5
-
6
- group :development, :test do
7
- # For debugger
8
- gem "pry-rails", "~> 0.3.2"
9
- gem "pry-debugger", "~> 0.2.2"
10
- gem "redis-namespace", "~> 1.4.1"
11
- end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module WeixinAuthorize
3
+ class ClientStorage < Storage
4
+
5
+ def valid?
6
+ super
7
+ end
8
+
9
+ def token_expired?
10
+ # 如果当前token过期时间小于现在的时间,则重新获取一次
11
+ client.expired_at <= Time.now.to_i
12
+ end
13
+
14
+ def authenticate
15
+ super
16
+ end
17
+
18
+ def access_token
19
+ super
20
+ client.access_token
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module WeixinAuthorize
3
+
4
+ class RedisStorage < Storage
5
+
6
+ def valid?
7
+ weixin_redis.del(client.redis_key)
8
+ super
9
+ end
10
+
11
+ def token_expired?
12
+ weixin_redis.hvals(client.redis_key).empty?
13
+ end
14
+
15
+ def authenticate
16
+ super
17
+ weixin_redis.hmset(client.redis_key, :access_token, client.access_token,
18
+ :expired_at, client.expired_at)
19
+ weixin_redis.expireat(client.redis_key, client.expired_at.to_i-10) # 提前10秒超时
20
+ end
21
+
22
+ def access_token
23
+ super
24
+ client.access_token = weixin_redis.hget(client.redis_key, "access_token")
25
+ client.expired_at = weixin_redis.hget(client.redis_key, "expired_at")
26
+ client.access_token
27
+ end
28
+
29
+ def weixin_redis
30
+ WeixinAuthorize.config.redis
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module WeixinAuthorize
3
+
4
+ class Storage
5
+
6
+ attr_accessor :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def self.init_with(client)
13
+ if WeixinAuthorize.config.redis.nil?
14
+ ClientStorage.new(client)
15
+ else
16
+ RedisStorage.new(client)
17
+ end
18
+ end
19
+
20
+ def valid?
21
+ valid_result = http_get_access_token
22
+ if valid_result.keys.include?("access_token")
23
+ set_access_token_for_client(valid_result)
24
+ return true
25
+ end
26
+ false
27
+ end
28
+
29
+ def token_expired?
30
+ raise NotImplementedError, "Subclasses must implement a token_expired? method"
31
+ end
32
+
33
+ def authenticate
34
+ raise "APPID or APPSECRET is invalid" if !valid?
35
+ set_access_token_for_client
36
+ end
37
+
38
+ def access_token
39
+ authenticate if token_expired?
40
+ end
41
+
42
+ def set_access_token_for_client(access_token_infos=nil)
43
+ token_infos = access_token_infos || http_get_access_token
44
+ client.access_token = token_infos["access_token"]
45
+ client.expired_at = Time.now.to_i + token_infos["expires_in"].to_i
46
+ end
47
+
48
+ def http_get_access_token
49
+ WeixinAuthorize.http_get_without_token("/token", authenticate_headers)
50
+ end
51
+
52
+ def authenticate_headers
53
+ {grant_type: "client_credential", appid: client.app_id, secret: client.app_secret}
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,3 @@
1
+ require "weixin_authorize/adapter/storage"
2
+ require "weixin_authorize/adapter/client_storage"
3
+ require "weixin_authorize/adapter/redis_storage"
@@ -7,19 +7,18 @@ module WeixinAuthorize
7
7
  # http请求方式: POST/FORM
8
8
  # http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
9
9
  # 支持传路径或者文件类型
10
- def upload_media(media, type)
10
+ def upload_media(media, media_type)
11
11
  file = media.is_a?(File) ? media : File.new(media)
12
12
  upload_media_url = "#{media_base_url}/upload"
13
- http_upload(upload_media_url, {media: file, media_type: type})
13
+ http_post(upload_media_url, {media: file}, {type: media_type}, "file")
14
14
  end
15
15
 
16
16
  # 目前仅仅把下载链接返回给第三方开发者,由第三方开发者处理下载
17
- # php重新写入文件方式:
18
- # http://www.cnblogs.com/txw1958/p/weixin80-upload-download-media-file.html
19
17
  def download_media_url(media_id)
20
- download_media_url = file_endpoint + "#{media_base_url}/get"
21
- download_media_url += "?access_token=#{get_access_token}"
22
- download_media_url += "&media_id=#{media_id}"
18
+ download_media_url = WeixinAuthorize.endpoint_url("file", "#{media_base_url}/get")
19
+ params = URI.encode_www_form("access_token" => get_access_token,
20
+ "media_id" => media_id)
21
+ download_media_url += "?#{params}"
23
22
  download_media_url
24
23
  end
25
24
 
@@ -28,15 +27,6 @@ module WeixinAuthorize
28
27
  def media_base_url
29
28
  "/media"
30
29
  end
31
-
32
- def http_upload(url, options)
33
- media_type = options.delete(:media_type)
34
- upload_url = file_endpoint + url
35
- upload_url += "?access_token=#{get_access_token}"
36
- upload_url += "&type=#{media_type}"
37
- JSON.parse(RestClient.post(upload_url, options))
38
- end
39
-
40
30
  end
41
31
  end
42
32
  end
@@ -6,7 +6,7 @@ module WeixinAuthorize
6
6
 
7
7
  # 临时二维码
8
8
  def create_qr_scene(scene_id, expire_seconds=1800)
9
- post_url = "#{qrcode_base_url}/create"
9
+ post_url = "#{qrcode_base_url}/create"
10
10
  qrcode_infos = {action_name: "QR_SCENE", expire_seconds: expire_seconds}
11
11
  qrcode_infos = qrcode_infos.merge(action_info(scene_id))
12
12
  http_post(post_url, qrcode_infos)
@@ -14,7 +14,7 @@ module WeixinAuthorize
14
14
 
15
15
  # 永久二维码
16
16
  def create_qr_limit_scene(scene_id)
17
- post_url = "#{qrcode_base_url}/create"
17
+ post_url = "#{qrcode_base_url}/create"
18
18
  qrcode_infos = {action_name: "QR_LIMIT_SCENE"}
19
19
  qrcode_infos = qrcode_infos.merge(action_info(scene_id))
20
20
  http_post(post_url, qrcode_infos)
@@ -22,7 +22,7 @@ module WeixinAuthorize
22
22
 
23
23
  # 通过ticket换取二维码, 直接访问即可显示!
24
24
  def qr_code_url(ticket)
25
- "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=#{ticket}"
25
+ WeixinAuthorize.mp_endpoint("/showqrcode?ticket=#{ticket}")
26
26
  end
27
27
 
28
28
  private
@@ -0,0 +1,6 @@
1
+ require "weixin_authorize/api/user"
2
+ require "weixin_authorize/api/menu"
3
+ require "weixin_authorize/api/custom"
4
+ require "weixin_authorize/api/groups"
5
+ require "weixin_authorize/api/qrcode"
6
+ require "weixin_authorize/api/media"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "redis"
3
- require 'digest'
3
+ require 'digest/md5'
4
4
  module WeixinAuthorize
5
5
 
6
6
  class Client
@@ -13,116 +13,40 @@ module WeixinAuthorize
13
13
 
14
14
  attr_accessor :app_id, :app_secret, :expired_at # Time.now + expires_in
15
15
  attr_accessor :access_token, :redis_key
16
+ attr_accessor :storage
16
17
 
17
18
  def initialize(app_id, app_secret, redis_key=nil)
18
19
  @app_id = app_id
19
20
  @app_secret = app_secret
20
21
  @expired_at = Time.now.to_i
21
22
  @redis_key = security_redis_key((redis_key || "weixin_" + app_id))
23
+ @storage = Storage.init_with(self)
22
24
  end
23
25
 
24
26
  # return token
25
27
  def get_access_token
26
- authenticate if token_expired?
27
- if !is_weixin_redis_blank?
28
- self.access_token = weixin_redis.hget(redis_key, "access_token")
29
- self.expired_at = weixin_redis.hget(redis_key, "expired_at")
30
- end
31
- @access_token
28
+ @storage.access_token
32
29
  end
33
30
 
34
31
  # 检查appid和app_secret是否有效。
35
32
  def is_valid?
36
- valid_result = http_get_access_token
37
- if valid_result.keys.include?("access_token")
38
- set_access_token_for_client(valid_result)
39
- return true
40
- end
41
- false
42
- end
43
-
44
- def token_expired?
45
- if is_weixin_redis_blank?
46
- # 如果当前token过期时间小于现在的时间,则重新获取一次
47
- @expired_at <= Time.now.to_i
48
- else
49
- weixin_redis.hvals(redis_key).empty?
50
- end
33
+ @storage.valid?
51
34
  end
52
35
 
53
36
  private
54
37
 
55
- # authenticate access_token
56
- def authenticate
57
- raise "APPID or APPSECRET is invalid" if !is_valid?
58
- if is_weixin_redis_blank?
59
- set_access_token_for_client
60
- else
61
- authenticate_with_redis
62
- end
63
- end
64
-
65
- def authenticate_with_redis
66
- set_access_token_for_client
67
- weixin_redis.hmset(redis_key, :access_token, access_token, :expired_at, expired_at)
68
- weixin_redis.expireat(redis_key, expired_at.to_i-10) # 提前10秒超时
69
- end
70
-
71
- def set_access_token_for_client(access_token_infos=nil)
72
- token_infos = access_token_infos || http_get_access_token
73
- self.access_token = token_infos["access_token"]
74
- self.expired_at = Time.now.to_i + token_infos["expires_in"].to_i
75
- end
76
-
77
- def http_get_access_token
78
- hash_infos = http_get_without_token("/token", authenticate_options)
79
- hash_infos
80
- end
81
-
82
- def authenticate_options
83
- {grant_type: "client_credential", appid: app_id, secret: app_secret}
84
- end
85
-
86
38
  def access_token_param
87
39
  {access_token: get_access_token}
88
40
  end
89
41
 
90
- def http_get_without_token(url, options={}, endpoint="plain")
91
- get_api_url = endpoint_url(endpoint) + url
92
- JSON.parse(RestClient.get(get_api_url, :params => options))
93
- end
94
-
95
- def http_get(url, options={})
96
- options = options.merge(access_token_param)
97
- http_get_without_token(url, options)
98
- end
99
-
100
- # Refactor
101
- def http_post(url, options={}, endpoint="plain")
102
- post_api_url = endpoint_url(endpoint) + url + "?access_token=#{get_access_token}"
103
- options = MultiJson.dump(options) # to json
104
- JSON.parse(RestClient.post(post_api_url, options))
105
- end
106
-
107
- def endpoint_url(endpoint)
108
- send("#{endpoint}_endpoint")
109
- end
110
-
111
- def plain_endpoint
112
- "https://api.weixin.qq.com/cgi-bin"
113
- end
114
-
115
- def file_endpoint
116
- "http://file.api.weixin.qq.com/cgi-bin"
117
- end
118
-
119
- def weixin_redis
120
- return nil if WeixinAuthorize.config.nil?
121
- @redis ||= WeixinAuthorize.config.redis
42
+ def http_get(url, headers={}, endpoint="plain")
43
+ headers = headers.merge(access_token_param)
44
+ WeixinAuthorize.http_get_without_token(url, headers, endpoint)
122
45
  end
123
46
 
124
- def is_weixin_redis_blank?
125
- weixin_redis.nil?
47
+ def http_post(url, payload={}, headers={}, endpoint="plain")
48
+ headers = {:params => access_token_param.merge(headers)}
49
+ WeixinAuthorize.http_post_without_token(url, payload, headers, endpoint)
126
50
  end
127
51
 
128
52
  def security_redis_key(key)
@@ -1,3 +1,3 @@
1
1
  module WeixinAuthorize
2
- VERSION = "1.5.5"
2
+ VERSION = "1.5.6"
3
3
  end
@@ -1,14 +1,46 @@
1
1
  require "rest-client"
2
2
  require "multi_json"
3
3
  require "weixin_authorize/config"
4
- require "weixin_authorize/api/user"
5
- require "weixin_authorize/api/menu"
6
- require "weixin_authorize/api/custom"
7
- require "weixin_authorize/api/groups"
8
- require "weixin_authorize/api/qrcode"
9
- require "weixin_authorize/api/media"
4
+ require "weixin_authorize/adapter"
5
+ require "weixin_authorize/api"
10
6
  require "weixin_authorize/client"
11
7
 
12
8
  module WeixinAuthorize
13
9
 
10
+ class << self
11
+
12
+ def http_get_without_token(url, headers={}, endpoint="plain")
13
+ get_api_url = endpoint_url(endpoint, url)
14
+ load_json(RestClient.get(get_api_url, :params => headers))
15
+ end
16
+
17
+ def http_post_without_token(url, payload={}, headers={}, endpoint="plain")
18
+ post_api_url = endpoint_url(endpoint, url)
19
+ payload = MultiJson.dump(payload) if endpoint == "plain" # to json
20
+ load_json(RestClient.post(post_api_url, payload, headers))
21
+ end
22
+
23
+ # return hash
24
+ def load_json(string)
25
+ JSON.parse(string)
26
+ end
27
+
28
+ def endpoint_url(endpoint, url)
29
+ send("#{endpoint}_endpoint") + url
30
+ end
31
+
32
+ def plain_endpoint
33
+ "https://api.weixin.qq.com/cgi-bin"
34
+ end
35
+
36
+ def file_endpoint
37
+ "http://file.api.weixin.qq.com/cgi-bin"
38
+ end
39
+
40
+ def mp_endpoint
41
+ "https://mp.weixin.qq.com/cgi-bin"
42
+ end
43
+
44
+ end
45
+
14
46
  end
@@ -11,7 +11,12 @@ describe WeixinAuthorize::Api::Groups do
11
11
 
12
12
  it "create a group" do
13
13
  response = $client.create_group(group_name)
14
- expect(response["group"]["name"]).to eq(group_name)
14
+ if !response["errcode"].nil?
15
+ expect(response.keys).to eq(["errcode", "errmsg"])
16
+ puts "SB WEIXIN says: system error"
17
+ else
18
+ expect(response["group"]["name"]).to eq(group_name)
19
+ end
15
20
  end
16
21
 
17
22
  it "get groups" do
@@ -26,11 +31,16 @@ describe WeixinAuthorize::Api::Groups do
26
31
 
27
32
  it "#update_group_name" do
28
33
  response = $client.create_group(group_name)
29
- expect(response["group"]["name"]).to eq(group_name)
30
- response = $client.update_group_name(response["group"]["id"], group_name_2)
31
- expect(response["errcode"]).to eq(0)
32
- groups = $client.groups
33
- expect(groups["groups"][-1]["name"]).to eq(group_name_2)
34
+ if !response["errcode"].nil?
35
+ expect(response.keys).to eq(["errcode", "errmsg"])
36
+ puts "SB WEIXIN says: system error"
37
+ else
38
+ expect(response["group"]["name"]).to eq(group_name)
39
+ response = $client.update_group_name(response["group"]["id"], group_name_2)
40
+ expect(response["errcode"]).to eq(0)
41
+ groups = $client.groups
42
+ expect(groups["groups"][-1]["name"]).to eq(group_name_2)
43
+ end
34
44
  end
35
45
 
36
46
  it "#update_group_for_openid" do
@@ -15,11 +15,11 @@ describe WeixinAuthorize::Api::Media do
15
15
  expect(response.keys).to eq(["type", "media_id", "created_at"])
16
16
  end
17
17
 
18
- # it "#download_media_url" do
19
- # image = $client.upload_media(image_file, "image")
20
- # media_id = image["media_id"]
21
- # response = $client.download_media_url(media_id)
22
- # response
23
- # end
18
+ it "#download_media_url return a String url" do
19
+ image = $client.upload_media(image_file, "image")
20
+ media_id = image["media_id"]
21
+ response = $client.download_media_url(media_id)
22
+ expect(response.class).to eq(String)
23
+ end
24
24
 
25
25
  end
@@ -7,6 +7,13 @@ describe WeixinAuthorize::Api::User do
7
7
  end
8
8
 
9
9
  it "can get followers infos" do
10
+ valid_info = $client.is_valid?
11
+ expect(valid_info).to eq(true)
12
+ followers = $client.followers
13
+ expect(followers.keys).to eq(["total", "count", "data", "next_openid"])
14
+
15
+ valid_info = $client.is_valid?
16
+ expect(valid_info).to eq(true)
10
17
  followers = $client.followers
11
18
  expect(followers.keys).to eq(["total", "count", "data", "next_openid"])
12
19
  end
data/spec/spec_helper.rb CHANGED
@@ -19,8 +19,6 @@ require "multi_json"
19
19
  require "redis"
20
20
  require "redis-namespace"
21
21
 
22
- require "pry-rails"
23
-
24
22
  redis = Redis.new(:host => "127.0.0.1",:port => "6379")
25
23
 
26
24
  namespace = "weixin_test:weixin_authorize"
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 1.3"
26
26
  spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "redis-namespace", "~> 1.4.1"
27
28
 
28
29
  spec.add_development_dependency "rspec", "~> 3.0.0.beta1"
29
30
 
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weixin_authorize
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.5
4
+ version: 1.5.6
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-28 00:00:00.000000000 Z
11
+ date: 2014-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.6.7
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.6.7
27
27
  - !ruby/object:Gem::Dependency
@@ -70,16 +70,30 @@ dependencies:
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: redis-namespace
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.4.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 1.4.1
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,11 @@ files:
108
122
  - README.md
109
123
  - Rakefile
110
124
  - lib/weixin_authorize.rb
125
+ - lib/weixin_authorize/adapter.rb
126
+ - lib/weixin_authorize/adapter/client_storage.rb
127
+ - lib/weixin_authorize/adapter/redis_storage.rb
128
+ - lib/weixin_authorize/adapter/storage.rb
129
+ - lib/weixin_authorize/api.rb
111
130
  - lib/weixin_authorize/api/custom.rb
112
131
  - lib/weixin_authorize/api/groups.rb
113
132
  - lib/weixin_authorize/api/media.rb
@@ -137,12 +156,12 @@ require_paths:
137
156
  - lib
138
157
  required_ruby_version: !ruby/object:Gem::Requirement
139
158
  requirements:
140
- - - '>='
159
+ - - ! '>='
141
160
  - !ruby/object:Gem::Version
142
161
  version: '0'
143
162
  required_rubygems_version: !ruby/object:Gem::Requirement
144
163
  requirements:
145
- - - '>='
164
+ - - ! '>='
146
165
  - !ruby/object:Gem::Version
147
166
  version: '0'
148
167
  requirements: []