usergrid_iron 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ # also allows hash or dot notation for entity properties
2
+ module Usergrid
3
+ class Entity < Resource
4
+
5
+ def initialize(url, api_url, options={}, response=nil, index=nil)
6
+ super url, api_url, options, response
7
+ @index = index
8
+ end
9
+
10
+ def data
11
+ get unless response
12
+ @index ? response.entities_data[@index] : response.entity_data
13
+ end
14
+
15
+ def data?
16
+ !!response
17
+ end
18
+
19
+ def resource
20
+ Resource.new url, api_url, options
21
+ end
22
+
23
+ def [](k)
24
+ data[k]
25
+ end
26
+
27
+ def []=(k,v)
28
+ data[k] = v
29
+ end
30
+
31
+ def collection
32
+ Collection.new url[0..url[0..-2].rindex('/')-1], api_url, options
33
+ end
34
+
35
+ def save
36
+ self.put data
37
+ end
38
+
39
+ def to_s
40
+ "resource: #{url}\ndata: #{data.pretty_inspect}"
41
+ end
42
+
43
+ private
44
+
45
+ def method_missing(method, *args, &block)
46
+ if data.respond_to?(method)
47
+ data.send(method, *args, &block)
48
+ elsif method[-1] == '=' && args.size == 1
49
+ data[method[0..-2]] = args[0]
50
+ else
51
+ super method, args, block
52
+ end
53
+ end
54
+
55
+ def respond_to?(method)
56
+ super.respond_to?(method) || data.respond_to?(method)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ module Usergrid
2
+ class Management < Resource
3
+
4
+ def initialize(api_url, options)
5
+ url = concat_urls(api_url, 'management')
6
+ super url, api_url, options
7
+ end
8
+
9
+ # one way: cannot delete organizations
10
+ def create_organization(organization, username, name, email, password)
11
+ data = { organization: organization,
12
+ username: username,
13
+ name: name,
14
+ email: email,
15
+ password: password }
16
+ self['organizations'].post data
17
+ end
18
+
19
+ def organizations
20
+ self[__method__].get
21
+ end
22
+
23
+ def organization(organization)
24
+ url = self["organizations/#{organization}"].url
25
+ Organization.new url, api_url, options
26
+ end
27
+
28
+ def users
29
+ self['users'].get
30
+ end
31
+
32
+ def user(name_or_uuid)
33
+ self["users/#{name_or_uuid}"].get
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,51 @@
1
+ require 'uri'
2
+ module Usergrid
3
+ class Organization < Resource
4
+
5
+ def initialize(url, api_url, options)
6
+ super url, api_url, options
7
+ end
8
+
9
+ def name
10
+ URI(url).path.split('/').last
11
+ end
12
+
13
+ def create_application(name)
14
+ self['applications'].post({ name: name })
15
+ application name
16
+ end
17
+
18
+ def applications(query=nil)
19
+ resource = self[__method__]
20
+ response = query ? resource.query(query) : resource.get
21
+ response.data['data'].collect do |k|
22
+ application concat_urls(api_url, k)
23
+ end
24
+ end
25
+
26
+ def application(name_or_uuid)
27
+ Usergrid::Application.new concat_urls(api_url, "#{name}/#{name_or_uuid}"), api_url, options
28
+ end
29
+
30
+ def users(query=nil)
31
+ self[__method__].query(query)
32
+ end
33
+
34
+ def user(user)
35
+ management.user(user)
36
+ end
37
+
38
+ def feed(query=nil)
39
+ self[__method__].query(query)
40
+ end
41
+
42
+ def credentials
43
+ self[__method__].get
44
+ end
45
+
46
+ def generate_credentials
47
+ self['credentials'].post nil
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,117 @@
1
+ require 'rest_client'
2
+
3
+ module Usergrid
4
+ class Resource < RestClient::Resource
5
+
6
+ DEFAULT_API_URL = 'https://api.usergrid.com'
7
+ TYPE_HEADERS = { :content_type => :json, :accept => :json }
8
+
9
+ attr_reader :current_user, :auth_token, :api_url
10
+
11
+ def initialize(resource_url=DEFAULT_API_URL, api_url=nil, options={}, response=nil)
12
+ options[:headers] = TYPE_HEADERS.merge options[:headers] || {}
13
+ @api_url = api_url || resource_url
14
+ self.response = response
15
+ super resource_url, options, &method(:handle_response)
16
+ end
17
+
18
+ # gets user token and automatically set auth header for future requests
19
+ # precondition: resource must already be set to the correct context (application or management)
20
+ def login(username, password)
21
+ params = { grant_type: "password", username: username, password: password }
22
+ response = self['token'].get({ params: params })
23
+ self.auth_token = response.data['access_token']
24
+ user_uuid = response.data['user']['uuid']
25
+ @current_user = self["/users/#{user_uuid}"].get.entity
26
+ response
27
+ end
28
+
29
+ # remove auth header for future requests
30
+ # only affects self and derivative resources
31
+ def logout
32
+ self.auth_token = nil
33
+ @current_user = nil
34
+ end
35
+
36
+ def logged_in?
37
+ !!@auth_token
38
+ end
39
+
40
+ def management
41
+ Usergrid::Management.new api_url, options
42
+ end
43
+
44
+ # application defaults to sandbox if none provided
45
+ def application(organization, application='sandbox')
46
+ Usergrid::Application.new concat_urls(api_url, "#{organization}/#{application}"), api_url, options
47
+ end
48
+
49
+ def query(query=nil, options={})
50
+ options = options.merge({ql: query}) if query
51
+ get({params: options})
52
+ end
53
+
54
+ def entity
55
+ response.entity
56
+ end
57
+
58
+ def collection
59
+ Collection.new url, api_url, options, response
60
+ end
61
+
62
+ # overridden to ensure sub resources are instances of this class
63
+ def [](suburl, &new_block)
64
+ case
65
+ when block_given? then Resource.new(concat_urls(url, suburl), api_url, options, &new_block)
66
+ when block then Resource.new(concat_urls(url, suburl), api_url, options, &block)
67
+ else
68
+ Resource.new(concat_urls(url, suburl), api_url, options)
69
+ end
70
+ end
71
+
72
+ def api_resource(suburl)
73
+ Resource.new(concat_urls(api_url, suburl), api_url, options)
74
+ end
75
+
76
+ def get(additional_headers={}, &block)
77
+ self.response = super additional_headers, &block
78
+ end
79
+
80
+ def post(payload, additional_headers={}, &block)
81
+ payload = payload.to_json if payload.is_a?(Hash) || payload.is_a?(Array)
82
+ self.response = super payload, additional_headers, &block
83
+ end
84
+
85
+ def put(payload, additional_headers={}, &block)
86
+ payload = payload.to_json if payload.is_a?(Hash) || payload.is_a?(Array)
87
+ self.response = super payload, additional_headers, &block
88
+ end
89
+
90
+ protected
91
+
92
+ attr_reader :response
93
+
94
+ def response=(response)
95
+ @response = response
96
+ end
97
+
98
+ def auth_token=(auth_token)
99
+ @auth_token = auth_token
100
+ if auth_token
101
+ @options[:headers].merge!({ Authorization: "Bearer #{auth_token}" })
102
+ else
103
+ @options[:headers].delete :Authorization if @options
104
+ end
105
+ end
106
+
107
+ # add verbose debugging of response body
108
+ def handle_response(response, request, result, &block)
109
+ LOG.debug "response.body = #{response}"
110
+ response = response.return!(request, result, &block)
111
+ response.resource = self
112
+ self.response = response
113
+ response
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,27 @@
1
+ class Hash
2
+
3
+ # recursive
4
+ def add_dot_notation!
5
+ add_dot_notation_recurse! self
6
+ end
7
+
8
+ # not recursive
9
+ def symbolize_keys
10
+ inject({}) do |options, (key, value)|
11
+ options[(key.to_sym rescue key) || key] = value
12
+ options
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def add_dot_notation_recurse!(_hash)
19
+ _hash.each do |k,v|
20
+ getter = k.to_sym; setter = "#{k}=".to_sym
21
+ _hash.define_singleton_method getter, lambda { _hash[k] } unless _hash.respond_to? getter
22
+ _hash.define_singleton_method setter, lambda { |v| _hash[k] = v } unless _hash.respond_to? setter
23
+ add_dot_notation_recurse!(v) if v.is_a? Hash
24
+ v.each { |e| add_dot_notation_recurse!(e) if e.is_a? Hash } if v.is_a? Array
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ module RestClient
2
+ module Response
3
+
4
+ def resource=(resource)
5
+ @resource = resource
6
+ end
7
+
8
+ def resource
9
+ @resource
10
+ end
11
+
12
+ def data
13
+ @data = JSON.parse(self).add_dot_notation! unless @data
14
+ @data
15
+ end
16
+
17
+ def collection
18
+ resource.collection
19
+ end
20
+
21
+ def multiple_entities?
22
+ entities_data = data['entities'] || data['data'] || data['messages']
23
+ entities_data.is_a? Array
24
+ end
25
+
26
+ def entities_data
27
+ return @entities_data if @entities_data
28
+ entities_data = data['entities'] || data['data'] || data['messages']
29
+ raise "unable to determine entities from: #{data}" unless entities_data.is_a?(Array)
30
+ entities_data.each do |e|
31
+ e['uri'] = resource.concat_urls(data['uri'], e['uuid']) if e['uuid']
32
+ end
33
+ @entities_data = entities_data
34
+ end
35
+
36
+ def entities
37
+ return @entities if @entities
38
+ index = -1
39
+ @entities = entities_data.collect do |e|
40
+ Usergrid::Entity.new e['uri'], resource.api_url, resource.options, self, index+=1
41
+ end
42
+ end
43
+
44
+ def entity_data
45
+ if multiple_entities?
46
+ entities_data.first
47
+ elsif data['data']
48
+ d = data['data']
49
+ d['uri'] = @resource.url
50
+ d
51
+ elsif data['organization']
52
+ d = data['organization']
53
+ d['uri'] = @resource.url
54
+ d
55
+ else
56
+ entities_data.first
57
+ end
58
+ end
59
+
60
+ def entity
61
+ Usergrid::Entity.new entity_data['uri'], resource.api_url, resource.options, self
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module Usergrid
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,77 @@
1
+ require 'simplecov'
2
+
3
+ require 'rspec'
4
+ require 'yaml'
5
+ require 'securerandom'
6
+ require_relative '../lib/usergrid'
7
+
8
+ LOG = Logger.new(STDOUT)
9
+ RestClient.log=LOG
10
+
11
+ SimpleCov.at_exit do
12
+ SimpleCov.result.format!
13
+ #index = File.join(SimpleCov.coverage_path, 'index.html')
14
+ #`open #{index}` if File.exists?(index)
15
+ end
16
+ SimpleCov.start
17
+
18
+ SPEC_SETTINGS = YAML::load_file(File.join File.dirname(__FILE__), 'spec_settings.yaml')
19
+
20
+ # ensure we are correctly setup (management login & organization)
21
+ management = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]).management
22
+ management.login SPEC_SETTINGS[:management][:username], SPEC_SETTINGS[:management][:password]
23
+
24
+ begin
25
+ management.create_organization(SPEC_SETTINGS[:organization][:name],
26
+ SPEC_SETTINGS[:organization][:username],
27
+ SPEC_SETTINGS[:organization][:username],
28
+ "#{SPEC_SETTINGS[:organization][:username]}@email.com",
29
+ SPEC_SETTINGS[:organization][:password])
30
+ LOG.info "created organization with user #{SPEC_SETTINGS[:organization][:username]}@email.com"
31
+ rescue
32
+ if JSON($!.response)['error'] == "duplicate_unique_property_exists"
33
+ LOG.debug "test organization exists"
34
+ else
35
+ raise $!
36
+ end
37
+ end
38
+
39
+ def app_endpoint
40
+ "#{SPEC_SETTINGS[:organization][:name]}/#{SPEC_SETTINGS[:application][:name]}"
41
+ end
42
+
43
+ def org_endpoint
44
+ "#{SPEC_SETTINGS[:organization][:name]}"
45
+ end
46
+
47
+ def create_random_application
48
+ management = login_management
49
+ organization = management.organization SPEC_SETTINGS[:organization][:name]
50
+
51
+ app_name = "_test_app_#{SecureRandom.hex}"
52
+ organization.create_application app_name
53
+ management.application SPEC_SETTINGS[:organization][:name], app_name
54
+ end
55
+
56
+ def delete_application(application)
57
+ management = login_management
58
+ application.auth_token = management.auth_token
59
+ application.delete
60
+ end
61
+
62
+ def create_random_user(application, login=false)
63
+ random = SecureRandom.hex
64
+ user_hash = {username: "username_#{random}",
65
+ name: "#{random} name",
66
+ email: "#{random}@email.com",
67
+ password: random}
68
+ entity = application['users'].post(user_hash).entity
69
+ application.login user_hash[:username], user_hash[:password] if login
70
+ entity
71
+ end
72
+
73
+ def login_management
74
+ management = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]).management
75
+ management.login SPEC_SETTINGS[:organization][:username], SPEC_SETTINGS[:organization][:password]
76
+ management
77
+ end