userapp 0.1.5
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.
- data/README.md +6 -0
- data/lib/userapp/api.rb +12 -0
- data/lib/userapp/client.rb +94 -0
- data/lib/userapp/client_options.rb +56 -0
- data/lib/userapp/errors.rb +21 -0
- data/lib/userapp/hash_utility.rb +29 -0
- data/lib/userapp/proxy_client.rb +64 -0
- data/lib/userapp/userapp.rb +11 -0
- data/lib/userapp/version.rb +3 -0
- data/lib/userapp.rb +4 -0
- metadata +66 -0
data/README.md
ADDED
data/lib/userapp/api.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'rest_client'
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../errors.rb', __FILE__)
|
|
4
|
+
require File.expand_path('../hash_utility.rb', __FILE__)
|
|
5
|
+
require File.expand_path('../client_options.rb', __FILE__)
|
|
6
|
+
|
|
7
|
+
module UserApp
|
|
8
|
+
class Client
|
|
9
|
+
attr_accessor :options
|
|
10
|
+
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
@options = self.get_options()
|
|
13
|
+
|
|
14
|
+
if args.length == 1 and args[0].class == Hash
|
|
15
|
+
@options.set(args[0])
|
|
16
|
+
else
|
|
17
|
+
if args.length >= 1
|
|
18
|
+
options.app_id = args[0]
|
|
19
|
+
end
|
|
20
|
+
if args.length >= 2
|
|
21
|
+
options.token = args[2]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_options(*args)
|
|
27
|
+
if self.options.nil?
|
|
28
|
+
self.options = UserApp::ClientOptions.get_global().copy()
|
|
29
|
+
end
|
|
30
|
+
return self.options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def call(version, service, method, arguments)
|
|
34
|
+
# Build the URL of the API to call
|
|
35
|
+
target_url = 'http' + (!self.options.secure || 's') + '://' + self.options.base_address + '/'
|
|
36
|
+
target_url << 'v' + version.to_s + '/' + service.to_s + '.' + method
|
|
37
|
+
|
|
38
|
+
if arguments.nil?
|
|
39
|
+
arguments = {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if self.get_options().debug
|
|
43
|
+
self.log("Sending HTTP POST request to '#{target_url}' with app_id '#{self.options.app_id}', token '#{self.options.token}' and arguments '#{arguments.to_json()}'.")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
resource = RestClient::Resource.new(target_url, self.options.app_id, self.options.token)
|
|
47
|
+
|
|
48
|
+
resource.post(
|
|
49
|
+
(arguments.nil? ? {} : arguments).to_json(),
|
|
50
|
+
:content_type => :json
|
|
51
|
+
){ |response, request, z_result, &block|
|
|
52
|
+
if self.get_options().debug
|
|
53
|
+
self.log("Recieved HTTP response with code '#{response.code}' and body '#{response.body}'.")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if response.code != 200 and response.code != 401
|
|
57
|
+
raise Error.new("Recieved HTTP status #{response.code}, expected 200.")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
result = HashUtility.convert_to_object(JSON.parse(response.body))
|
|
61
|
+
is_error_result = result.respond_to?('error_code')
|
|
62
|
+
|
|
63
|
+
if self.options.throw_errors and is_error_result
|
|
64
|
+
if result.error_code == 'INVALID_SERVICE'
|
|
65
|
+
raise InvalidServiceException.new("Service '#{service}' does not exist.")
|
|
66
|
+
elsif result.error_code == 'INVALID_METHOD'
|
|
67
|
+
raise InvalidServiceException.new("Method '#{method}' on service '#{service}' does not exist.")
|
|
68
|
+
else
|
|
69
|
+
raise ServiceError.new(result.error_code, result.message)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if service == 'user'
|
|
74
|
+
if not is_error_result and method == 'login'
|
|
75
|
+
self.options.token = result.token
|
|
76
|
+
elsif method == 'logout'
|
|
77
|
+
self.options.token = nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return result
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def log(message)
|
|
86
|
+
options = self.get_options()
|
|
87
|
+
if !options.logger.nil? and options.logger.respond_to?('debug')
|
|
88
|
+
options.logger.debug(message)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
protected :log
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module UserApp
|
|
4
|
+
class ClientOptions
|
|
5
|
+
@@instance = nil
|
|
6
|
+
|
|
7
|
+
attr_accessor :app_id
|
|
8
|
+
attr_accessor :token
|
|
9
|
+
attr_accessor :base_address
|
|
10
|
+
attr_accessor :throw_errors
|
|
11
|
+
attr_accessor :secure
|
|
12
|
+
attr_accessor :debug
|
|
13
|
+
attr_accessor :logger
|
|
14
|
+
|
|
15
|
+
def initialize(*args)
|
|
16
|
+
@base_address = 'api.userapp.io'
|
|
17
|
+
@throw_errors = true
|
|
18
|
+
@secure = true
|
|
19
|
+
@debug = false
|
|
20
|
+
|
|
21
|
+
if !args.nil?
|
|
22
|
+
if args.length == 1 and args[0].class == Hash
|
|
23
|
+
args = args[0]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
self.set(args)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def logger()
|
|
31
|
+
if @debug and @logger.nil?
|
|
32
|
+
@logger = Logger.new(STDOUT)
|
|
33
|
+
end
|
|
34
|
+
return @logger
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def set(args)
|
|
38
|
+
args.each do | key, value |
|
|
39
|
+
if key and self.respond_to?(key)
|
|
40
|
+
self.send("#{key}=", value)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def copy()
|
|
46
|
+
return ClientOptions.new(self.instance_variables)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.get_global(*args)
|
|
50
|
+
if @@instance.nil?
|
|
51
|
+
@@instance = ClientOptions.new(args)
|
|
52
|
+
end
|
|
53
|
+
return @@instance
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module UserApp
|
|
2
|
+
class Error < Exception
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class InvalidServiceException < Error
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class InvalidMethodException < Error
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ServiceError < Error
|
|
12
|
+
attr :error_code
|
|
13
|
+
def initialize(error_code, message)
|
|
14
|
+
@error_code = error_code
|
|
15
|
+
super(message)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class NotAuthorizedError < ServiceError
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
3
|
+
module UserApp
|
|
4
|
+
class HashUtility
|
|
5
|
+
def self.convert_to_object(source)
|
|
6
|
+
if source.kind_of?(Hash)
|
|
7
|
+
result = OpenStruct.new(source)
|
|
8
|
+
|
|
9
|
+
source.each do | key, value |
|
|
10
|
+
if source[key].kind_of?(Array) || source[key].is_a?(Hash)
|
|
11
|
+
result.send("#{key}=", self.convert_to_object(value))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
return result
|
|
16
|
+
elsif source.kind_of?(Array)
|
|
17
|
+
result = []
|
|
18
|
+
|
|
19
|
+
source.each do | value |
|
|
20
|
+
result << self.convert_to_object(value)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return result
|
|
24
|
+
else
|
|
25
|
+
return source
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../client.rb', __FILE__)
|
|
4
|
+
require File.expand_path('../errors.rb', __FILE__)
|
|
5
|
+
|
|
6
|
+
module UserApp
|
|
7
|
+
class ProxyClient
|
|
8
|
+
attr_accessor :client
|
|
9
|
+
attr_accessor :services
|
|
10
|
+
attr_accessor :service_name
|
|
11
|
+
attr_accessor :service_version
|
|
12
|
+
|
|
13
|
+
def initialize(*args)
|
|
14
|
+
@services = Hash.new()
|
|
15
|
+
if (args.length == 2 or args.length == 3) and args[0].is_a?(Client)
|
|
16
|
+
@client = args[0]
|
|
17
|
+
@service_name = args[1]
|
|
18
|
+
@service_version = args.length == 2 ? 1 : args[2]
|
|
19
|
+
else
|
|
20
|
+
self.service_version = 1
|
|
21
|
+
@client = Client.new(*args)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_options()
|
|
26
|
+
return self.client.get_options()
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def method_missing(method_id, *args)
|
|
30
|
+
if args.length > 0
|
|
31
|
+
if self.service_name.nil?
|
|
32
|
+
raise UserAppError.new("Unable to call method on base service.")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
self.client.call(self.service_version, self.service_name, method_id.to_s(), args[0])
|
|
36
|
+
else
|
|
37
|
+
target_service = nil
|
|
38
|
+
target_version = nil
|
|
39
|
+
|
|
40
|
+
if self.services[method_id]
|
|
41
|
+
return self.services[method_id]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if self.service_name.nil? and method_id.length >= 2 and method_id[0] == 'v' and method_id[1, method_id.length-1].match(/\A[0-9]+\Z/)
|
|
45
|
+
target_version = method_id[1].to_i
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if target_version.nil?
|
|
49
|
+
target_version = self.service_version
|
|
50
|
+
if !self.service_name.nil?
|
|
51
|
+
target_service = self.service_name.to_s + '.' + method_id.to_s
|
|
52
|
+
else
|
|
53
|
+
target_service = method_id.to_s
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
proxy = ProxyClient.new(self.client, target_service, target_version)
|
|
58
|
+
self.services[method_id] = proxy
|
|
59
|
+
|
|
60
|
+
return proxy
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module UserApp
|
|
2
|
+
class Client
|
|
3
|
+
require File.expand_path('../client.rb', __FILE__)
|
|
4
|
+
end
|
|
5
|
+
class ProxyClient
|
|
6
|
+
require File.expand_path('../proxy_client.rb', __FILE__)
|
|
7
|
+
end
|
|
8
|
+
class API < ProxyClient
|
|
9
|
+
require File.expand_path('../api.rb', __FILE__)
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/userapp.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: userapp
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.5
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Robin Orheden
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2014-01-16 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: json
|
|
16
|
+
requirement: &9937560 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *9937560
|
|
25
|
+
description: User management and authentication for your Ruby app.
|
|
26
|
+
email: robin.orheden@userapp.io
|
|
27
|
+
executables: []
|
|
28
|
+
extensions: []
|
|
29
|
+
extra_rdoc_files: []
|
|
30
|
+
files:
|
|
31
|
+
- lib/userapp.rb
|
|
32
|
+
- lib/userapp/userapp.rb
|
|
33
|
+
- lib/userapp/errors.rb
|
|
34
|
+
- lib/userapp/api.rb
|
|
35
|
+
- lib/userapp/version.rb
|
|
36
|
+
- lib/userapp/proxy_client.rb
|
|
37
|
+
- lib/userapp/client_options.rb
|
|
38
|
+
- lib/userapp/hash_utility.rb
|
|
39
|
+
- lib/userapp/client.rb
|
|
40
|
+
- README.md
|
|
41
|
+
homepage: https://www.userapp.io/
|
|
42
|
+
licenses:
|
|
43
|
+
- MIT
|
|
44
|
+
post_install_message:
|
|
45
|
+
rdoc_options: []
|
|
46
|
+
require_paths:
|
|
47
|
+
- lib
|
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ! '>='
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '0'
|
|
60
|
+
requirements: []
|
|
61
|
+
rubyforge_project:
|
|
62
|
+
rubygems_version: 1.8.11
|
|
63
|
+
signing_key:
|
|
64
|
+
specification_version: 3
|
|
65
|
+
summary: UserApp
|
|
66
|
+
test_files: []
|