facebook-signed-request 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,33 +3,38 @@ Usage
3
3
 
4
4
 
5
5
  ```ruby
6
- require 'facebook-signed-request'
7
- request = Facebook::SignedRequest.new( params[:signed_request], secret )
8
-
9
- request.valid?
10
- # => true / false
11
-
12
- request.errors
13
- # => [
14
- # "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/",
15
- # "Invalid Base64 encoding for signature",
16
- # "Invalid Base64 Encoding for data",
17
- # "Invalid JSON object",
18
- # "Invalid Algorithm. Expected: HMAC-SHA256",
19
- # "Signatures do not match. #{expected} but was #{computed}"
20
- #]
21
-
22
- request.data
23
- # => {
24
- # "algorithm"=>"HMAC-SHA256",
25
- # "expires"=>1308988800,
26
- # "issued_at"=>1308985018,
27
- # "oauth_token"=>"114998258593813|2.AQBAttRlLVnwqNPZ.3600.1308988800…",
28
- # "user"=> {
29
- # "country"=>"de",
30
- # "locale"=>"en_US",
31
- # "age"=>{"min"=>21}
32
- # },
33
- # "user_id"=>"100000656666199"
34
- # }
6
+ require 'facebook-signed-request'
7
+ request = Facebook::SignedRequest.new( params[:signed_request], secret )
8
+
9
+ request.valid?
10
+ # => true / false
11
+
12
+ request.errors
13
+ # => [
14
+ # "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/",
15
+ # "Invalid Base64 encoding for signature",
16
+ # "Invalid Base64 Encoding for data",
17
+ # "Invalid JSON object",
18
+ # "Invalid Algorithm. Expected: HMAC-SHA256",
19
+ # "Signatures do not match. #{expected} but was #{computed}"
20
+ #]
21
+
22
+ request.data
23
+ # => {
24
+ # "algorithm"=>"HMAC-SHA256",
25
+ # "expires"=>1308988800,
26
+ # "issued_at"=>1308985018,
27
+ # "oauth_token"=>"114998258593813|2.AQBAttRlLVnwqNPZ.3600.1308988800…",
28
+ # "user"=> {
29
+ # "country"=>"de",
30
+ # "locale"=>"en_US",
31
+ # "age"=>{"min"=>21}
32
+ # },
33
+ # "user_id"=>"100000656666199"
34
+ # }
35
+
36
+
37
+ Facebook::SignedRequest.encode_and_sign { :foo => bar }
38
+ # => g_eE3hoQDPKFusHcc_Tj7k2xxo3mCKsOEXKMViq0pAY=.eyJmb28iOiJiYXIifQ==
39
+
35
40
  ```
@@ -3,6 +3,19 @@ module Facebook
3
3
 
4
4
  class << self
5
5
  attr_accessor :secret
6
+
7
+ # Creates a signed_request with correctly padded Base64 encoding.
8
+ # Mostly useful for testing.
9
+ def encode_and_sign options
10
+ encoded_data = Base64.strict_encode64( options.to_json )
11
+
12
+ digestor = Digest::HMAC.new( @secret, Digest::SHA256 )
13
+ signature = digestor.digest( encoded_data )
14
+ encoded_signature = Base64.strict_encode64( signature )
15
+ encoded_signature = encoded_signature.gsub('+','_').gsub('/', '_')
16
+
17
+ "#{encoded_signature}.#{encoded_data}"
18
+ end
6
19
  end
7
20
 
8
21
  attr_reader :errors, :signature, :data
@@ -12,7 +25,24 @@ module Facebook
12
25
  @secret = options[:secret] || SignedRequest.secret
13
26
  @errors = []
14
27
 
28
+ check_for_invalid_arguments
29
+
30
+ @signature = extract_request_signature
31
+ @payload = extract_request_payload
32
+ @data = parse_request_playload
33
+
34
+ validate_algorithm
35
+ validate_signature
36
+ validate_timestamp if options[:strict] == true
37
+ end
38
+
39
+ def valid?
40
+ @errors.empty?
41
+ end
15
42
 
43
+ private
44
+
45
+ def check_for_invalid_arguments
16
46
  if @encoded_signature.nil? || @encoded_data.nil?
17
47
  raise ArgumentError, "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/"
18
48
  end
@@ -24,14 +54,6 @@ module Facebook
24
54
  unless @secret.is_a?( String )
25
55
  raise ArgumentError, "Secret should be a String"
26
56
  end
27
-
28
- @signature = extract_request_signature
29
- @payload = extract_request_payload
30
- @data = parse_request_playload
31
-
32
- validate_algorithm
33
- validate_signature
34
- validate_timestamp if options[:strict] == true
35
57
  end
36
58
 
37
59
  def base64_url_decode( encoded_string )
@@ -39,15 +61,9 @@ module Facebook
39
61
  Base64.strict_decode64(encoded_string.gsub("-", "+").gsub("_", "/"))
40
62
  end
41
63
 
42
- def valid?
43
- @errors.empty?
44
- end
45
-
46
- private
47
-
48
64
  def extract_request_signature
49
65
  begin
50
- return base64_url_decode(@encoded_signature).unpack('H*')[0]
66
+ return base64_url_decode(@encoded_signature)
51
67
  rescue ArgumentError
52
68
  @errors << "Invalid Base64 encoding for signature"
53
69
  return nil
@@ -80,7 +96,7 @@ module Facebook
80
96
 
81
97
  def validate_signature
82
98
  digestor = Digest::HMAC.new( @secret, Digest::SHA256 )
83
- computed_signature = digestor.hexdigest( @encoded_data )
99
+ computed_signature = digestor.digest( @encoded_data )
84
100
 
85
101
  if @signature != computed_signature
86
102
  message = "Signatures do not match. " \
@@ -1,5 +1,5 @@
1
1
  module Facebook
2
2
  class SignedRequest
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -77,4 +77,22 @@ class SignedRequestTest < Test::Unit::TestCase
77
77
  )
78
78
  end
79
79
 
80
+ test "encode and sign request params" do
81
+ request_1 = Facebook::SignedRequest.new( @valid_request )
82
+
83
+ reencoded_request = Facebook::SignedRequest.encode_and_sign(request_1.data)
84
+
85
+ sig_1, data_1 = @valid_request.split(".", 2)
86
+ sig_2, data_2 = reencoded_request.split(".", 2)
87
+
88
+ # Simulate invalid raw Base64 from Facebook by removing padding
89
+ assert_equal sig_1, sig_2.gsub(/=+$/, "")
90
+ assert_equal data_1, data_2.gsub(/=+$/, "")
91
+
92
+ request_2 = Facebook::SignedRequest.new( reencoded_request )
93
+
94
+ assert_equal request_1.signature, request_2.signature
95
+ assert_equal request_1.data, request_2.data
96
+ end
97
+
80
98
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facebook-signed-request
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: