userbin 0.4.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +87 -111
- data/lib/userbin.rb +18 -39
- data/lib/userbin/configuration.rb +14 -16
- data/lib/userbin/errors.rb +5 -0
- data/lib/userbin/helpers.rb +83 -0
- data/lib/userbin/jwt.rb +40 -0
- data/lib/userbin/models/base.rb +24 -0
- data/lib/userbin/models/challenge.rb +4 -0
- data/lib/userbin/models/session.rb +11 -0
- data/lib/userbin/models/user.rb +9 -0
- data/lib/userbin/request.rb +99 -0
- data/lib/userbin/utils.rb +28 -0
- data/lib/userbin/version.rb +1 -1
- data/spec/configuration_spec.rb +8 -0
- data/spec/fixtures/vcr_cassettes/session_create.yml +47 -0
- data/spec/fixtures/vcr_cassettes/session_refresh.yml +47 -0
- data/spec/fixtures/vcr_cassettes/session_verify.yml +47 -0
- data/spec/fixtures/vcr_cassettes/user_find.yml +44 -0
- data/spec/fixtures/vcr_cassettes/user_find_non_existing.yml +42 -0
- data/spec/fixtures/vcr_cassettes/user_import.yml +46 -0
- data/spec/fixtures/vcr_cassettes/user_update.yml +47 -0
- data/spec/helpers_spec.rb +38 -0
- data/spec/jwt_spec.rb +67 -0
- data/spec/models/session_spec.rb +33 -0
- data/spec/models/user_spec.rb +43 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/utils_spec.rb +36 -0
- metadata +128 -36
- data/lib/userbin/authentication.rb +0 -132
- data/lib/userbin/basic_auth.rb +0 -31
- data/lib/userbin/current.rb +0 -17
- data/lib/userbin/events.rb +0 -40
- data/lib/userbin/rails/auth_helpers.rb +0 -22
- data/lib/userbin/railtie.rb +0 -14
- data/lib/userbin/session.rb +0 -26
- data/lib/userbin/userbin.rb +0 -104
- data/spec/session_spec.rb +0 -40
- data/spec/userbin_spec.rb +0 -102
data/lib/userbin/jwt.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
|
3
|
+
module Userbin
|
4
|
+
class JWT
|
5
|
+
attr_reader :header
|
6
|
+
attr_reader :payload
|
7
|
+
|
8
|
+
def initialize(jwt)
|
9
|
+
begin
|
10
|
+
raise Userbin::SecurityError, 'Empty JWT' unless jwt
|
11
|
+
@payload = ::JWT.decode(jwt, Userbin.config.api_secret, true) do |header|
|
12
|
+
@header = header.with_indifferent_access
|
13
|
+
Userbin.config.api_secret # used by the 'key finder' in the JWT gem
|
14
|
+
end.with_indifferent_access
|
15
|
+
rescue ::JWT::DecodeError => e
|
16
|
+
raise Userbin::SecurityError.new(e)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def expired?
|
21
|
+
Time.now.utc > Time.at(@header['exp']).utc
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json
|
25
|
+
@payload
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_token
|
29
|
+
::JWT.encode(@payload, Userbin.config.api_secret, "HS256", @header)
|
30
|
+
end
|
31
|
+
|
32
|
+
def app_id
|
33
|
+
@header['aud']
|
34
|
+
end
|
35
|
+
|
36
|
+
def merge!(payload = {})
|
37
|
+
@payload.merge!(payload)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'her'
|
2
|
+
|
3
|
+
module Userbin
|
4
|
+
class Base
|
5
|
+
include Her::Model
|
6
|
+
use_api Userbin::API
|
7
|
+
|
8
|
+
METHODS.each do |method|
|
9
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
10
|
+
def self.instance_#{method}(action)
|
11
|
+
instance_custom(:#{method}, action)
|
12
|
+
end
|
13
|
+
RUBY
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.instance_custom(method, action)
|
17
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
18
|
+
def #{action}(params={})
|
19
|
+
self.class.#{method}("\#{request_path}/#{action}", params)
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Userbin
|
2
|
+
module Request
|
3
|
+
|
4
|
+
def self.client_user_agent
|
5
|
+
@uname ||= get_uname
|
6
|
+
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
7
|
+
|
8
|
+
{
|
9
|
+
:bindings_version => Userbin::VERSION,
|
10
|
+
:lang => 'ruby',
|
11
|
+
:lang_version => lang_version,
|
12
|
+
:platform => RUBY_PLATFORM,
|
13
|
+
:publisher => 'userbin',
|
14
|
+
:uname => @uname
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_uname
|
19
|
+
`uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
|
20
|
+
rescue Errno::ENOMEM => ex # couldn't create subprocess
|
21
|
+
"uname lookup failed"
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Faraday middleware
|
26
|
+
#
|
27
|
+
module Middleware
|
28
|
+
# Sets credentials dynamically, allowing them to change between requests.
|
29
|
+
#
|
30
|
+
class BasicAuth < Faraday::Middleware
|
31
|
+
def initialize(app, api_secret)
|
32
|
+
super(app)
|
33
|
+
@api_secret = api_secret
|
34
|
+
end
|
35
|
+
|
36
|
+
def call(env)
|
37
|
+
value = Base64.encode64("#{@api_secret || Userbin.config.api_secret}:")
|
38
|
+
value.gsub!("\n", '')
|
39
|
+
env[:request_headers]["Authorization"] = "Basic #{value}"
|
40
|
+
@app.call(env)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Adds details about current environment
|
45
|
+
#
|
46
|
+
class EnvironmentHeaders < Faraday::Middleware
|
47
|
+
def call(env)
|
48
|
+
begin
|
49
|
+
env[:request_headers]["X-Userbin-Client-User-Agent"] =
|
50
|
+
MultiJson.encode(Userbin::Request.client_user_agent)
|
51
|
+
rescue => error; end
|
52
|
+
|
53
|
+
env[:request_headers]["User-Agent"] =
|
54
|
+
"Userbin/v1 RubyBindings/#{Userbin::VERSION}"
|
55
|
+
|
56
|
+
@app.call(env)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Adds request context like IP address and user agent to any request.
|
61
|
+
#
|
62
|
+
class ContextHeaders < Faraday::Middleware
|
63
|
+
def call(env)
|
64
|
+
userbin_headers = RequestStore.store.fetch(:userbin_headers, [])
|
65
|
+
userbin_headers.each do |key, value|
|
66
|
+
header =
|
67
|
+
"X-Userbin-#{key.to_s.gsub('_', '-').gsub(/\w+/) {|m| m.capitalize}}"
|
68
|
+
env[:request_headers][header] = value
|
69
|
+
end
|
70
|
+
@app.call(env)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class JSONParser < Her::Middleware::DefaultParseJSON
|
75
|
+
# This method is triggered when the response has been received. It modifies
|
76
|
+
# the value of `env[:body]`.
|
77
|
+
#
|
78
|
+
# @param [Hash] env The response environment
|
79
|
+
# @private
|
80
|
+
def on_complete(env)
|
81
|
+
env[:body] = '{}' if [204, 405].include?(env[:status])
|
82
|
+
env[:body] = case env[:status]
|
83
|
+
when 403
|
84
|
+
raise Userbin::ForbiddenError.new(
|
85
|
+
MultiJson.decode(env[:body])['message'])
|
86
|
+
when 419
|
87
|
+
raise Userbin::UserUnauthorizedError.new(
|
88
|
+
MultiJson.decode(env[:body])['message'])
|
89
|
+
when 400..599
|
90
|
+
raise Userbin::Error.new(MultiJson.decode(env[:body])['message'])
|
91
|
+
else
|
92
|
+
parse(env[:body])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# TODO: scope Userbin::Utils
|
2
|
+
|
3
|
+
module Userbin
|
4
|
+
class << self
|
5
|
+
def setup_api(api_secret = nil)
|
6
|
+
api_endpoint = ENV.fetch('USERBIN_API_ENDPOINT') {
|
7
|
+
"https://secure.userbin.com/v1"
|
8
|
+
}
|
9
|
+
|
10
|
+
Her::API.setup url: api_endpoint do |c|
|
11
|
+
c.use Userbin::Request::Middleware::BasicAuth, api_secret
|
12
|
+
c.use Userbin::Request::Middleware::EnvironmentHeaders
|
13
|
+
c.use Userbin::Request::Middleware::ContextHeaders
|
14
|
+
c.use FaradayMiddleware::EncodeJson
|
15
|
+
c.use Userbin::Request::Middleware::JSONParser
|
16
|
+
c.use Faraday::Adapter::NetHttp
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def with_context(opts, &block)
|
21
|
+
return block.call unless opts
|
22
|
+
RequestStore.store[:userbin_headers] = {}
|
23
|
+
RequestStore.store[:userbin_headers][:ip] = opts[:ip] if opts[:ip]
|
24
|
+
RequestStore.store[:userbin_headers][:user_agent] = opts[:user_agent] if opts[:user_agent]
|
25
|
+
block.call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/userbin/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://secretkey:@secure.userbin.com/v1/users/user-2412/sessions
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"user":{"email":"valid@example.com"}}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.0
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 201
|
21
|
+
message: 'Created '
|
22
|
+
headers:
|
23
|
+
Content-Type:
|
24
|
+
- application/json
|
25
|
+
Content-Length:
|
26
|
+
- '716'
|
27
|
+
X-Ua-Compatible:
|
28
|
+
- IE=Edge
|
29
|
+
Etag:
|
30
|
+
- '"c323dc2244006efcc5629936b73749ff"'
|
31
|
+
Cache-Control:
|
32
|
+
- max-age=0, private, must-revalidate
|
33
|
+
Server:
|
34
|
+
- WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24)
|
35
|
+
Date:
|
36
|
+
- Wed, 07 May 2014 16:21:05 GMT
|
37
|
+
Connection:
|
38
|
+
- Keep-Alive
|
39
|
+
Set-Cookie:
|
40
|
+
- _ubt=; expires=Thu, 01-Jan-1970 00:00:00 GMT
|
41
|
+
body:
|
42
|
+
encoding: UTF-8
|
43
|
+
string: '{"id":"S2odxReZnGqhqxPaQ7V7kNkLoXkGZPFz","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImlzcyI6InVzZXItMjQxMiIsInN1YiI6IlMyb2R4UmVabkdxaHF4UGFRN1Y3a05rTG9Ya0daUEZ6IiwiYXVkIjoiODAwMDAwMDAwMDAwMDAwIiwiZXhwIjoxMzk5NDc5Njc1LCJpYXQiOjEzOTk0Nzk2NjUsImp0aSI6MH0.eyJjaGFsbGVuZ2UiOnsiaWQiOiJUVENqd3VyM3lwbTRUR1ZwWU43cENzTXFxOW9mWEVBSCIsInR5cGUiOiJvdHBfYXV0aGVudGljYXRvciJ9fQ.LT9mUzJEbsizbFxcpMo3zbms0aCDBzfgMbveMGSi1-s","user":{"id":"8Fpmj9asxpq4mwGzx48MP1EQhdWUHDeb","local_id":"user-2412","created_at":"2014-05-07T15:33:58Z","updated_at":"2014-05-07T16:04:56Z","email":"valid@example.com","username":"valid@example.com","name":"New
|
44
|
+
Name","first_name":null,"last_name":null,"image":null,"status":"ACTIVE","mfa_enabled":true}}'
|
45
|
+
http_version:
|
46
|
+
recorded_at: Wed, 07 May 2014 16:21:05 GMT
|
47
|
+
recorded_with: VCR 2.9.0
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://secretkey:@secure.userbin.com/v1/sessions/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImlzcyI6InVzZXItMjQxMiIsInN1YiI6IlMyb2R4UmVabkdxaHF4UGFRN1Y3a05rTG9Ya0daUEZ6IiwiYXVkIjoiODAwMDAwMDAwMDAwMDAwIiwiZXhwIjoxMzk5NDc5Njc1LCJpYXQiOjEzOTk0Nzk2NjUsImp0aSI6MH0.eyJjaGFsbGVuZ2UiOnsiaWQiOiJUVENqd3VyM3lwbTRUR1ZwWU43cENzTXFxOW9mWEVBSCIsInR5cGUiOiJvdHBfYXV0aGVudGljYXRvciJ9fQ.LT9mUzJEbsizbFxcpMo3zbms0aCDBzfgMbveMGSi1-s/refresh
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"user":{"name":"New Name"}}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.0
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 201
|
21
|
+
message: 'Created '
|
22
|
+
headers:
|
23
|
+
Content-Type:
|
24
|
+
- application/json
|
25
|
+
Content-Length:
|
26
|
+
- '716'
|
27
|
+
X-Ua-Compatible:
|
28
|
+
- IE=Edge
|
29
|
+
Etag:
|
30
|
+
- '"537ee28e9894002208f8f645f6dd2987"'
|
31
|
+
Cache-Control:
|
32
|
+
- max-age=0, private, must-revalidate
|
33
|
+
Server:
|
34
|
+
- WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24)
|
35
|
+
Date:
|
36
|
+
- Wed, 07 May 2014 16:21:55 GMT
|
37
|
+
Connection:
|
38
|
+
- Keep-Alive
|
39
|
+
Set-Cookie:
|
40
|
+
- _ubt=; expires=Thu, 01-Jan-1970 00:00:00 GMT
|
41
|
+
body:
|
42
|
+
encoding: UTF-8
|
43
|
+
string: '{"id":"S2odxReZnGqhqxPaQ7V7kNkLoXkGZPFz","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImlzcyI6InVzZXItMjQxMiIsInN1YiI6IlMyb2R4UmVabkdxaHF4UGFRN1Y3a05rTG9Ya0daUEZ6IiwiYXVkIjoiODAwMDAwMDAwMDAwMDAwIiwiZXhwIjoxMzk5NDc5NzI1LCJpYXQiOjEzOTk0Nzk3MTUsImp0aSI6MX0.eyJjaGFsbGVuZ2UiOnsiaWQiOiJUVENqd3VyM3lwbTRUR1ZwWU43cENzTXFxOW9mWEVBSCIsInR5cGUiOiJvdHBfYXV0aGVudGljYXRvciJ9fQ.2UuUgl8jKkl1lhU0d2nSKmiw-Qzz130A9XJd7-swvv8","user":{"id":"8Fpmj9asxpq4mwGzx48MP1EQhdWUHDeb","local_id":"user-2412","created_at":"2014-05-07T15:33:58Z","updated_at":"2014-05-07T16:21:55Z","email":"valid@example.com","username":"valid@example.com","name":"New
|
44
|
+
Name","first_name":null,"last_name":null,"image":null,"status":"ACTIVE","mfa_enabled":true}}'
|
45
|
+
http_version:
|
46
|
+
recorded_at: Wed, 07 May 2014 16:21:55 GMT
|
47
|
+
recorded_with: VCR 2.9.0
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://secretkey:@secure.userbin.com/v1/sessions/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImlzcyI6InVzZXItMjQxMiIsInN1YiI6IlMyb2R4UmVabkdxaHF4UGFRN1Y3a05rTG9Ya0daUEZ6IiwiYXVkIjoiODAwMDAwMDAwMDAwMDAwIiwiZXhwIjoxMzk5NDc5Njc1LCJpYXQiOjEzOTk0Nzk2NjUsImp0aSI6MH0.eyJjaGFsbGVuZ2UiOnsiaWQiOiJUVENqd3VyM3lwbTRUR1ZwWU43cENzTXFxOW9mWEVBSCIsInR5cGUiOiJvdHBfYXV0aGVudGljYXRvciJ9fQ.LT9mUzJEbsizbFxcpMo3zbms0aCDBzfgMbveMGSi1-s/verify
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"response":"017010"}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.0
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 201
|
21
|
+
message: 'Created '
|
22
|
+
headers:
|
23
|
+
Content-Type:
|
24
|
+
- application/json
|
25
|
+
Content-Length:
|
26
|
+
- '609'
|
27
|
+
X-Ua-Compatible:
|
28
|
+
- IE=Edge
|
29
|
+
Etag:
|
30
|
+
- '"27b68d405c62c2c4c2a23acafde76b26"'
|
31
|
+
Cache-Control:
|
32
|
+
- max-age=0, private, must-revalidate
|
33
|
+
Server:
|
34
|
+
- WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24)
|
35
|
+
Date:
|
36
|
+
- Wed, 07 May 2014 16:22:55 GMT
|
37
|
+
Connection:
|
38
|
+
- Keep-Alive
|
39
|
+
Set-Cookie:
|
40
|
+
- _ubt=; expires=Thu, 01-Jan-1970 00:00:00 GMT
|
41
|
+
body:
|
42
|
+
encoding: UTF-8
|
43
|
+
string: '{"id":"S2odxReZnGqhqxPaQ7V7kNkLoXkGZPFz","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImlzcyI6InVzZXItMjQxMiIsInN1YiI6IlMyb2R4UmVabkdxaHF4UGFRN1Y3a05rTG9Ya0daUEZ6IiwiYXVkIjoiODAwMDAwMDAwMDAwMDAwIiwiZXhwIjoxMzk5NDc5NzI1LCJpYXQiOjEzOTk0Nzk3MTUsImp0aSI6MX0.e30.IRwMbLDd2LqRHB_QZvzG47eTr5vPCBrdWI6xPOPa6x4","user":{"id":"8Fpmj9asxpq4mwGzx48MP1EQhdWUHDeb","local_id":"user-2412","created_at":"2014-05-07T15:33:58Z","updated_at":"2014-05-07T16:21:55Z","email":"valid@example.com","username":"valid@example.com","name":"New
|
44
|
+
Name","first_name":null,"last_name":null,"image":null,"status":"ACTIVE","mfa_enabled":true}}'
|
45
|
+
http_version:
|
46
|
+
recorded_at: Wed, 07 May 2014 16:22:55 GMT
|
47
|
+
recorded_with: VCR 2.9.0
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://secretkey:@secure.userbin.com/v1/users/9RA2j3cYDxt8gefQUduKnxUxRRGy6Rz4
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.0
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- '*/*'
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Date:
|
22
|
+
- Fri, 18 Apr 2014 23:16:44 GMT
|
23
|
+
Status:
|
24
|
+
- 200 OK
|
25
|
+
Connection:
|
26
|
+
- close
|
27
|
+
Content-Type:
|
28
|
+
- application/json
|
29
|
+
Content-Length:
|
30
|
+
- '328'
|
31
|
+
Set-Cookie:
|
32
|
+
- _ubt=; expires=Thu, 01-Jan-1970 00:00:00 GMT
|
33
|
+
X-Ua-Compatible:
|
34
|
+
- IE=Edge
|
35
|
+
Etag:
|
36
|
+
- '"73f5664d599cfbc71df7850ca66cda3d"'
|
37
|
+
Cache-Control:
|
38
|
+
- max-age=0, private, must-revalidate
|
39
|
+
body:
|
40
|
+
encoding: UTF-8
|
41
|
+
string: '{"id":"9RA2j3cYDxt8gefQUduKnxUxRRGy6Rz4","created_at":"2014-04-18T13:30:22Z","updated_at":"2014-04-18T13:33:51Z","email":"brissmyr@gmail.com","username":"brissmyr@gmail.com","name":null,"first_name":null,"last_name":null,"image":null,"status":"ACTIVE","email_verification_token":"NhFy8wBYccLsEoL-kAVt","identities":[]}'
|
42
|
+
http_version:
|
43
|
+
recorded_at: Fri, 18 Apr 2014 23:16:44 GMT
|
44
|
+
recorded_with: VCR 2.9.0
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://secretkey:@secure.userbin.com/v1/users/non_existing
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.0
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- '*/*'
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 404
|
19
|
+
message: Not Found
|
20
|
+
headers:
|
21
|
+
Date:
|
22
|
+
- Fri, 18 Apr 2014 23:29:27 GMT
|
23
|
+
Status:
|
24
|
+
- 404 Not Found
|
25
|
+
Connection:
|
26
|
+
- close
|
27
|
+
Content-Type:
|
28
|
+
- application/json
|
29
|
+
Content-Length:
|
30
|
+
- '42'
|
31
|
+
Set-Cookie:
|
32
|
+
- _ubt=; expires=Thu, 01-Jan-1970 00:00:00 GMT
|
33
|
+
X-Ua-Compatible:
|
34
|
+
- IE=Edge
|
35
|
+
Cache-Control:
|
36
|
+
- no-cache
|
37
|
+
body:
|
38
|
+
encoding: UTF-8
|
39
|
+
string: '{"type":"not_found","message":"Not found"}'
|
40
|
+
http_version:
|
41
|
+
recorded_at: Fri, 18 Apr 2014 23:29:27 GMT
|
42
|
+
recorded_with: VCR 2.9.0
|