weixin_authorize 1.6.0 → 1.6.2
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 +4 -4
- data/.rspec +1 -0
- data/Gemfile +4 -5
- data/README.md +19 -8
- data/lib/weixin_authorize.rb +31 -13
- data/lib/weixin_authorize/api.rb +3 -0
- data/lib/weixin_authorize/api/data_cube.rb +8 -0
- data/lib/weixin_authorize/api/mass.rb +78 -0
- data/lib/weixin_authorize/api/media.rb +50 -4
- data/lib/weixin_authorize/api/oauth.rb +38 -0
- data/lib/weixin_authorize/api/template.rb +34 -0
- data/lib/weixin_authorize/api/user.rb +18 -0
- data/lib/weixin_authorize/client.rb +45 -16
- data/lib/weixin_authorize/config.rb +12 -3
- data/lib/weixin_authorize/handler/result_handler.rb +1 -0
- data/lib/weixin_authorize/js_ticket/object_store.rb +21 -0
- data/lib/weixin_authorize/js_ticket/redis_store.rb +41 -0
- data/lib/weixin_authorize/js_ticket/store.rb +40 -0
- data/lib/weixin_authorize/token/object_store.rb +25 -0
- data/lib/weixin_authorize/token/redis_store.rb +35 -0
- data/lib/weixin_authorize/token/store.rb +72 -0
- data/lib/weixin_authorize/version.rb +1 -1
- data/spec/1_fetch_access_token_spec.rb +0 -1
- data/spec/2_fetch_jsticket_spec.rb +10 -0
- data/spec/api/custom_spec.rb +0 -2
- data/spec/api/groups_spec.rb +0 -1
- data/spec/api/mass_spec.rb +65 -0
- data/spec/api/media_spec.rb +1 -3
- data/spec/api/menu_spec.rb +0 -2
- data/spec/api/qrcode_spec.rb +3 -5
- data/spec/api/user_spec.rb +5 -2
- data/spec/spec_helper.rb +7 -4
- data/weixin_authorize.gemspec +5 -5
- metadata +31 -20
- data/lib/weixin_authorize/adapter/client_storage.rb +0 -23
- data/lib/weixin_authorize/adapter/redis_storage.rb +0 -34
- data/lib/weixin_authorize/adapter/storage.rb +0 -73
@@ -9,12 +9,21 @@ module WeixinAuthorize
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def weixin_redis
|
12
|
-
return nil if
|
13
|
-
@redis ||=
|
12
|
+
return nil if config.nil?
|
13
|
+
@redis ||= config.redis
|
14
|
+
end
|
15
|
+
|
16
|
+
# 可选配置: RestClient timeout, etc.
|
17
|
+
# key 必须是符号
|
18
|
+
def rest_client_options
|
19
|
+
if config.nil?
|
20
|
+
return {timeout: 5, open_timeout: 5, verify_ssl: true}
|
21
|
+
end
|
22
|
+
config.rest_client_options
|
14
23
|
end
|
15
24
|
end
|
16
25
|
|
17
26
|
class Config
|
18
|
-
attr_accessor :redis
|
27
|
+
attr_accessor :redis, :rest_client_options
|
19
28
|
end
|
20
29
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module WeixinAuthorize
|
2
|
+
module JsTicket
|
3
|
+
class ObjectStore < Store
|
4
|
+
|
5
|
+
def jsticket_expired?
|
6
|
+
# 如果当前token过期时间小于现在的时间,则重新获取一次
|
7
|
+
client.jsticket_expired_at <= Time.now.to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
def jsticket
|
11
|
+
super
|
12
|
+
client.jsticket
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh_jsticket
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module WeixinAuthorize
|
2
|
+
module JsTicket
|
3
|
+
class RedisStore < Store
|
4
|
+
JSTICKET = "jsticket"
|
5
|
+
EXPIRED_AT = "expired_at"
|
6
|
+
|
7
|
+
def jsticket_expired?
|
8
|
+
weixin_redis.hvals(client.jsticket_redis_key).empty?
|
9
|
+
end
|
10
|
+
|
11
|
+
def refresh_jsticket
|
12
|
+
super
|
13
|
+
weixin_redis.hmset(
|
14
|
+
client.jsticket_redis_key,
|
15
|
+
JSTICKET,
|
16
|
+
client.jsticket,
|
17
|
+
EXPIRED_AT,
|
18
|
+
client.jsticket_expired_at
|
19
|
+
)
|
20
|
+
weixin_redis.expireat(
|
21
|
+
client.jsticket_redis_key,
|
22
|
+
client.jsticket_expired_at.to_i
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def jsticket
|
27
|
+
super
|
28
|
+
client.jsticket = weixin_redis.hget(client.jsticket_redis_key, JSTICKET)
|
29
|
+
client.jsticket_expired_at = weixin_redis.hget(
|
30
|
+
client.jsticket_redis_key,
|
31
|
+
EXPIRED_AT
|
32
|
+
)
|
33
|
+
client.jsticket
|
34
|
+
end
|
35
|
+
|
36
|
+
def weixin_redis
|
37
|
+
WeixinAuthorize.weixin_redis
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module JsTicket
|
4
|
+
class Store
|
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.weixin_redis.nil?
|
14
|
+
ObjectStore.new(client)
|
15
|
+
else
|
16
|
+
RedisStore.new(client)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def jsticket_expired?
|
21
|
+
raise NotImplementedError, "Subclasses must implement a jsticket_expired? method"
|
22
|
+
end
|
23
|
+
|
24
|
+
def refresh_jsticket
|
25
|
+
set_jsticket
|
26
|
+
end
|
27
|
+
|
28
|
+
def jsticket
|
29
|
+
refresh_jsticket if jsticket_expired?
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_jsticket
|
33
|
+
result = client.http_get("/ticket/getticket", {type: 1}).result
|
34
|
+
client.jsticket = result["ticket"]
|
35
|
+
client.jsticket_expired_at = result["expires_in"] + Time.now.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Token
|
4
|
+
class ObjectStore < Store
|
5
|
+
|
6
|
+
def valid?
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def token_expired?
|
11
|
+
# 如果当前token过期时间小于现在的时间,则重新获取一次
|
12
|
+
client.expired_at <= Time.now.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh_token
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def access_token
|
20
|
+
super
|
21
|
+
client.access_token
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Token
|
4
|
+
class RedisStore < Store
|
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 refresh_token
|
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.weixin_redis
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module WeixinAuthorize
|
3
|
+
module Token
|
4
|
+
class Store
|
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.weixin_redis.nil?
|
14
|
+
ObjectStore.new(client)
|
15
|
+
else
|
16
|
+
RedisStore.new(client)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
authenticate["valid"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticate
|
25
|
+
auth_result = http_get_access_token
|
26
|
+
auth = false
|
27
|
+
if auth_result.is_ok?
|
28
|
+
set_access_token(auth_result.result)
|
29
|
+
auth = true
|
30
|
+
end
|
31
|
+
{"valid" => auth, "handler" => auth_result}
|
32
|
+
end
|
33
|
+
|
34
|
+
def refresh_token
|
35
|
+
handle_valid_exception
|
36
|
+
set_access_token
|
37
|
+
end
|
38
|
+
|
39
|
+
def access_token
|
40
|
+
refresh_token if token_expired?
|
41
|
+
end
|
42
|
+
|
43
|
+
def token_expired?
|
44
|
+
raise NotImplementedError, "Subclasses must implement a token_expired? method"
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_access_token(access_token_infos=nil)
|
48
|
+
token_infos = access_token_infos || http_get_access_token.result
|
49
|
+
client.access_token = token_infos["access_token"]
|
50
|
+
client.expired_at = Time.now.to_i + token_infos["expires_in"].to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
def http_get_access_token
|
54
|
+
WeixinAuthorize.http_get_without_token("/token", authenticate_headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
def authenticate_headers
|
58
|
+
{grant_type: GRANT_TYPE, appid: client.app_id, secret: client.app_secret}
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def handle_valid_exception
|
64
|
+
auth_result = authenticate
|
65
|
+
if !auth_result["valid"]
|
66
|
+
result_handler = auth_result["handler"]
|
67
|
+
raise ValidAccessTokenException, result_handler.full_error_message
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
describe WeixinAuthorize::Client do
|
2
|
+
describe "#get jsticket" do
|
3
|
+
it "return the same jsticket in the same thing twice" do
|
4
|
+
js_ticket_1 = $client.get_jsticket
|
5
|
+
sleep 5
|
6
|
+
js_ticket_2 = $client.get_jsticket
|
7
|
+
expect(js_ticket_1).to eq(js_ticket_2)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/spec/api/custom_spec.rb
CHANGED
data/spec/api/groups_spec.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe WeixinAuthorize::Api::Mass do
|
4
|
+
|
5
|
+
let(:image_jpg_path) do
|
6
|
+
"#{File.dirname(__FILE__)}/medias/ruby-logo.jpg"
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:news_media_1) do
|
10
|
+
{
|
11
|
+
"thumb_media_id" => "",
|
12
|
+
"author" => "lanrion",
|
13
|
+
"title" => "Happy Day",
|
14
|
+
"content_source_url" => "www.qq.com",
|
15
|
+
"content" => "content",
|
16
|
+
"digest" => "digest"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:image_media_id) do
|
21
|
+
# Get image media_id
|
22
|
+
image_media = $client.upload_media(image_jpg_path, "image")
|
23
|
+
media_id = image_media.result["media_id"]
|
24
|
+
media_id
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:mass_media_id) do
|
28
|
+
media = {"thumb_media_id" => image_media_id}
|
29
|
+
news_media = news_media_1.merge(media)
|
30
|
+
|
31
|
+
# upload news media
|
32
|
+
response = $client.upload_mass_news([news_media])
|
33
|
+
mass_media_id = response.result["media_id"]
|
34
|
+
mass_media_id
|
35
|
+
end
|
36
|
+
|
37
|
+
it "#upload_mass_news" do
|
38
|
+
media = {"thumb_media_id" => image_media_id}
|
39
|
+
news_media = news_media_1.merge(media)
|
40
|
+
|
41
|
+
# upload news media
|
42
|
+
response = $client.upload_mass_news([news_media])
|
43
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
44
|
+
expect(response.result.keys).to eq(["type", "media_id", "created_at"])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "#mass_with_group with mpnews" do
|
48
|
+
response = $client.mass_with_group("1", "mass_group_text", "text")
|
49
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#mass_with_openids with mpnews and can delete message" do
|
53
|
+
response = $client.mass_with_openids([ENV["OPENID"]], mass_media_id)
|
54
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
55
|
+
expect(response.result.keys).to eq(["msg_id"])
|
56
|
+
delete_res = $client.mass_delete_with_msgid(response.result["msg_id"])
|
57
|
+
expect(delete_res.code).to eq(WeixinAuthorize::OK_CODE)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "#mass_preview can preview by openid" do
|
61
|
+
response = $client.mass_preview(ENV["OPENID"], "mass_text", "text")
|
62
|
+
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/spec/api/media_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
1
|
describe WeixinAuthorize::Api::Media do
|
4
2
|
|
5
3
|
let(:image_jpg_path) do
|
@@ -19,7 +17,7 @@ describe WeixinAuthorize::Api::Media do
|
|
19
17
|
end
|
20
18
|
|
21
19
|
let(:remote_png_path) do
|
22
|
-
"
|
20
|
+
"https://ruby-china-files.b0.upaiyun.com/user/big_avatar/273.jpg"
|
23
21
|
end
|
24
22
|
|
25
23
|
let(:remote_jpg_path) do
|
data/spec/api/menu_spec.rb
CHANGED
data/spec/api/qrcode_spec.rb
CHANGED
@@ -1,20 +1,18 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
1
|
describe WeixinAuthorize::Api::Qrcode do
|
4
2
|
|
5
3
|
it "#create_qr_scene" do
|
6
4
|
response = $client.create_qr_scene("123")
|
7
5
|
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
8
|
-
expect(response.result.keys).to eq(["ticket", "expire_seconds"])
|
6
|
+
expect(response.result.keys).to eq(["ticket", "expire_seconds", "url"])
|
9
7
|
expect(response.result["expire_seconds"]).to eq(1800)
|
10
8
|
end
|
11
9
|
|
12
10
|
it "#create_qr_limit_scene" do
|
13
11
|
response = $client.create_qr_limit_scene("1234")
|
14
12
|
expect(response.code).to eq(WeixinAuthorize::OK_CODE)
|
15
|
-
expect(response.result.keys).to eq(["ticket"])
|
13
|
+
expect(response.result.keys).to eq(["ticket", "url"])
|
16
14
|
end
|
17
|
-
|
15
|
+
|
18
16
|
it "#return_qr_url" do
|
19
17
|
response = $client.create_qr_limit_scene("1234")
|
20
18
|
qr_url = $client.qr_code_url(response.result["ticket"])
|
data/spec/api/user_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
1
|
describe WeixinAuthorize::Api::User do
|
4
2
|
it "can get a weixin User info" do
|
5
3
|
user_info = $client.user(ENV["OPENID"])
|
@@ -20,4 +18,9 @@ describe WeixinAuthorize::Api::User do
|
|
20
18
|
expect(followers.code).to eq(WeixinAuthorize::OK_CODE)
|
21
19
|
expect(followers.result.keys).to eq(["total", "count", "data", "next_openid"])
|
22
20
|
end
|
21
|
+
|
22
|
+
it "can update user remark" do
|
23
|
+
user_info = $client.update_remark(ENV["OPENID"], "dylan")
|
24
|
+
expect(user_info.code).to eq(WeixinAuthorize::OK_CODE)
|
25
|
+
end
|
23
26
|
end
|