gooddata 0.6.11 → 0.6.12

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +34 -1
  5. data/CLI.md +1 -1
  6. data/authors.sh +4 -0
  7. data/lib/gooddata.rb +1 -1
  8. data/lib/gooddata/cli/commands/api_cmd.rb +0 -2
  9. data/lib/gooddata/cli/commands/auth_cmd.rb +0 -3
  10. data/lib/gooddata/cli/commands/console_cmd.rb +1 -2
  11. data/lib/gooddata/cli/commands/domain_cmd.rb +0 -2
  12. data/lib/gooddata/cli/commands/process_cmd.rb +0 -2
  13. data/lib/gooddata/cli/commands/project_cmd.rb +0 -2
  14. data/lib/gooddata/cli/commands/projects_cmd.rb +0 -2
  15. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +2 -3
  16. data/lib/gooddata/cli/commands/scaffold_cmd.rb +0 -3
  17. data/lib/gooddata/cli/commands/user_cmd.rb +0 -2
  18. data/lib/gooddata/cli/shared.rb +1 -2
  19. data/lib/gooddata/commands/datawarehouse.rb +24 -0
  20. data/lib/gooddata/commands/process.rb +0 -1
  21. data/lib/gooddata/commands/project.rb +1 -1
  22. data/lib/gooddata/commands/scaffold.rb +0 -1
  23. data/lib/gooddata/core/connection.rb +376 -0
  24. data/lib/gooddata/core/logging.rb +13 -0
  25. data/lib/gooddata/core/rest.rb +40 -16
  26. data/lib/gooddata/exceptions/user_in_different_domain.rb +11 -0
  27. data/lib/gooddata/extensions/enumerable.rb +8 -0
  28. data/lib/gooddata/goodzilla/goodzilla.rb +24 -0
  29. data/lib/gooddata/helpers/global_helpers.rb +126 -12
  30. data/lib/gooddata/mixins/author.rb +11 -5
  31. data/lib/gooddata/mixins/is_dimension.rb +13 -0
  32. data/lib/gooddata/mixins/md_object_indexer.rb +17 -1
  33. data/lib/gooddata/mixins/md_object_query.rb +10 -2
  34. data/lib/gooddata/mixins/md_relations.rb +2 -2
  35. data/lib/gooddata/mixins/rest_resource.rb +1 -0
  36. data/lib/gooddata/models/data_result.rb +0 -1
  37. data/lib/gooddata/models/datawarehouse.rb +90 -0
  38. data/lib/gooddata/models/domain.rb +202 -76
  39. data/lib/gooddata/models/execution.rb +11 -0
  40. data/lib/gooddata/models/from_wire.rb +4 -4
  41. data/lib/gooddata/models/invitation.rb +0 -5
  42. data/lib/gooddata/models/membership.rb +121 -91
  43. data/lib/gooddata/models/metadata.rb +1 -2
  44. data/lib/gooddata/models/metadata/attribute.rb +7 -0
  45. data/lib/gooddata/models/metadata/dashboard.rb +1 -1
  46. data/lib/gooddata/models/metadata/dimension.rb +52 -0
  47. data/lib/gooddata/models/metadata/fact.rb +1 -1
  48. data/lib/gooddata/models/metadata/label.rb +21 -7
  49. data/lib/gooddata/models/metadata/metric.rb +1 -23
  50. data/lib/gooddata/models/metadata/report.rb +2 -2
  51. data/lib/gooddata/models/metadata/report_definition.rb +22 -2
  52. data/lib/gooddata/models/metadata/variable.rb +81 -0
  53. data/lib/gooddata/models/model.rb +2 -1
  54. data/lib/gooddata/models/process.rb +3 -4
  55. data/lib/gooddata/models/profile.rb +50 -82
  56. data/lib/gooddata/models/project.rb +170 -213
  57. data/lib/gooddata/models/project_blueprint.rb +14 -5
  58. data/lib/gooddata/models/project_creator.rb +2 -2
  59. data/lib/gooddata/models/schedule.rb +10 -8
  60. data/lib/gooddata/models/to_wire.rb +2 -2
  61. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +67 -0
  62. data/lib/gooddata/models/user_filters/user_filter.rb +96 -0
  63. data/lib/gooddata/models/user_filters/user_filter_builder.rb +409 -0
  64. data/lib/gooddata/{rest/connections/connections.rb → models/user_filters/user_filters.rb} +1 -0
  65. data/lib/gooddata/models/user_filters/variable_user_filter.rb +14 -0
  66. data/lib/gooddata/rest/client.rb +32 -21
  67. data/lib/gooddata/rest/connection.rb +283 -11
  68. data/lib/gooddata/rest/connections/rest_client_connection.rb +47 -109
  69. data/lib/gooddata/version.rb +1 -1
  70. data/spec/data/column_based_permissions.csv +7 -0
  71. data/spec/data/column_based_permissions2.csv +6 -0
  72. data/spec/data/hello_world_process/hello_world.rb +3 -1
  73. data/spec/data/line_based_permissions.csv +3 -0
  74. data/spec/data/m_n_model/blueprint.json +76 -0
  75. data/spec/data/{model_view.json → wire_models/model_view.json} +0 -0
  76. data/spec/data/wire_models/nu_model.json +3046 -0
  77. data/spec/helpers/process_helper.rb +2 -2
  78. data/spec/helpers/project_helper.rb +29 -0
  79. data/spec/helpers/schedule_helper.rb +1 -1
  80. data/spec/integration/command_datawarehouse_spec.rb +32 -0
  81. data/spec/integration/create_project_spec.rb +0 -1
  82. data/spec/integration/full_process_schedule_spec.rb +13 -5
  83. data/spec/integration/full_project_spec.rb +2 -1
  84. data/spec/integration/over_to_user_filters_spec.rb +92 -0
  85. data/spec/integration/project_spec.rb +233 -0
  86. data/spec/integration/rest_spec.rb +209 -0
  87. data/spec/integration/user_filters_spec.rb +193 -0
  88. data/spec/integration/variables_spec.rb +196 -0
  89. data/spec/unit/commands/command_auth_spec.rb +0 -7
  90. data/spec/unit/commands/command_process_spec.rb +10 -13
  91. data/spec/unit/core/connection_spec.rb +0 -19
  92. data/spec/unit/helpers/global_helpers_spec.rb +57 -0
  93. data/spec/unit/models/domain_spec.rb +80 -40
  94. data/spec/unit/models/from_wire_spec.rb +8 -1
  95. data/spec/unit/models/params_spec.rb +6 -6
  96. data/spec/unit/models/profile_spec.rb +23 -22
  97. data/spec/unit/models/project_blueprint_spec.rb +1 -6
  98. data/spec/unit/models/project_spec.rb +331 -286
  99. data/spec/unit/models/schedule_spec.rb +39 -14
  100. data/spec/unit/models/user_filters_spec.rb +89 -0
  101. data/spec/unit/models/variable_spec.rb +259 -0
  102. metadata +31 -7
  103. data/lib/gooddata/rest/connections/dummy_connection.rb +0 -52
  104. data/spec/unit/core/rest_spec.rb +0 -106
@@ -14,14 +14,14 @@ module GoodData
14
14
 
15
15
  # Returns which objects uses this MD resource
16
16
  def usedby(key = nil, opts = { :client => client, :project => project })
17
- dependency("#{project.md['usedby2']}/#{obj_id}", key, opts)
17
+ dependency("#{project.md['usedby2']}/#{obj_id}", key, { :client => client, :project => project }.merge(opts))
18
18
  end
19
19
 
20
20
  alias_method :used_by, :usedby
21
21
 
22
22
  # Returns which objects this MD resource uses
23
23
  def using(key = nil, opts = { :client => client, :project => project })
24
- dependency("#{project.md['using2']}/#{obj_id}", key, opts)
24
+ dependency("#{project.md['using2']}/#{obj_id}", key, { :client => client, :project => project }.merge(opts))
25
25
  end
26
26
 
27
27
  def usedby?(obj, opts = { :client => client, :project => project })
@@ -29,6 +29,7 @@ module GoodData
29
29
  base.send :include, GoodData::Mixin::NotMetric
30
30
  base.send :include, GoodData::Mixin::NotLabel
31
31
  base.send :include, GoodData::Mixin::MdRelations
32
+ base.send :include, GoodData::Mixin::Author
32
33
 
33
34
  base.extend GoodData::Mixin::MdObjId
34
35
  base.extend GoodData::Mixin::MdObjectQuery
@@ -1,7 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require_relative '../extensions/big_decimal'
4
-
5
4
  require_relative '../rest/object'
6
5
 
7
6
  module GoodData
@@ -0,0 +1,90 @@
1
+ # encoding: UTF-8
2
+ require_relative '../rest/resource'
3
+
4
+ module GoodData
5
+ class DataWarehouse < GoodData::Rest::Resource
6
+ class << self
7
+ CREATE_URL = '/gdc/datawarehouse/instances'
8
+
9
+ # Create a data warehouse from given attributes
10
+ # Expected keys:
11
+ # - :title (mandatory)
12
+ # - :auth_token (mandatory)
13
+ # - :summary
14
+ def create(opts)
15
+ GoodData.logger.info "Creating warehouse #{opts[:title]}"
16
+
17
+ c = client(opts)
18
+ fail ArgumentError, 'No :client specified' if c.nil?
19
+
20
+ auth_token = opts[:auth_token]
21
+ fail ArgumentError, 'You have to provide your token for creating projects as :auth_token parameter' if auth_token.nil? || auth_token.empty?
22
+
23
+ title = opts[:title]
24
+ fail ArgumentError, 'You have to provide a title for creating warehouse as :title parameter' if title.nil? || title.empty?
25
+
26
+ json = {
27
+ 'instance' => {
28
+ 'title' => title,
29
+ 'description' => opts[:description] || opts[:summary] || 'No summary',
30
+ 'authorizationToken' => auth_token
31
+ }
32
+ }
33
+ # do the first post
34
+ res = c.post(CREATE_URL, json)
35
+
36
+ # wait until the instance is created
37
+ final_res = c.poll_on_response(res['asyncTask']['links']['poll'], :sleep_interval => 3) do |r|
38
+ r['asyncTask']['links']['instance'].nil?
39
+ end
40
+
41
+ # get the json of the created instance
42
+ final_json = c.get(final_res['asyncTask']['links']['instance'])
43
+
44
+ # create the public facing object
45
+ c.create(DataWarehouse, final_json)
46
+ end
47
+ end
48
+ attr_accessor :json
49
+
50
+ alias_method :to_json, :json
51
+ alias_method :raw_data, :json
52
+
53
+ def initialize(json)
54
+ super
55
+ @json = json
56
+ end
57
+
58
+ def title
59
+ json['instance']['title']
60
+ end
61
+
62
+ def summary
63
+ json['instance']['description']
64
+ end
65
+
66
+ def status
67
+ json['instance']['status']
68
+ end
69
+
70
+ def uri
71
+ json['instance']['links']['self']
72
+ end
73
+
74
+ def id
75
+ uri.split('/')[-1]
76
+ end
77
+
78
+ def delete
79
+ if state == 'DELETED'
80
+ fail "Warehouse '#{title}' with id #{uri} is already deleted"
81
+ end
82
+ client.delete(uri)
83
+ end
84
+
85
+ # alias methods to prevent confusion and support the same keys
86
+ # project has.
87
+ alias_method :state, :status
88
+ alias_method :description, :summary
89
+ end
90
+ end
@@ -3,7 +3,7 @@
3
3
  require 'cgi'
4
4
 
5
5
  require_relative 'profile'
6
-
6
+ require_relative '../extensions/enumerable'
7
7
  require_relative '../rest/object'
8
8
 
9
9
  module GoodData
@@ -18,6 +18,7 @@ module GoodData
18
18
  # @param domain_name [String] Domain name
19
19
  # @return [String] Domain object instance
20
20
  def [](domain_name, options = { :client => GoodData.connection })
21
+ return domain_name if domain_name.is_a?(Domain)
21
22
  c = client(options)
22
23
  fail "Using pseudo-id 'all' is not supported by GoodData::Domain" if domain_name.to_s == 'all'
23
24
  c.create(GoodData::Domain, domain_name)
@@ -29,19 +30,21 @@ module GoodData
29
30
  # @param login [String] Login of user to be invited
30
31
  # @param password [String] Default preset password
31
32
  # @return [Object] Raw response
32
- def add_user(opts)
33
+ def add_user(user_data, name = nil, opts = { :client => GoodData.connection })
33
34
  generated_pass = rand(10E10).to_s
35
+ domain_name = name || user_data[:domain]
36
+ user_data = user_data.to_hash
34
37
  data = {
35
- :login => opts[:login],
36
- :firstName => opts[:first_name] || 'FirstName',
37
- :lastName => opts[:last_name] || 'LastName',
38
- :password => opts[:password] || generated_pass,
39
- :verifyPassword => opts[:password] || generated_pass,
40
- :email => opts[:login]
38
+ :login => user_data[:login] || user_data[:email],
39
+ :firstName => user_data[:first_name] || 'FirstName',
40
+ :lastName => user_data[:last_name] || 'LastName',
41
+ :password => user_data[:password] || generated_pass,
42
+ :verifyPassword => user_data[:password] || generated_pass,
43
+ :email => user_data[:email] || user_data[:login]
41
44
  }
42
45
 
43
46
  # Optional authentication modes
44
- tmp = opts[:authentication_modes]
47
+ tmp = user_data[:authentication_modes]
45
48
  if tmp
46
49
  if tmp.is_a? Array
47
50
  data[:authenticationModes] = tmp
@@ -51,36 +54,40 @@ module GoodData
51
54
  end
52
55
 
53
56
  # Optional company
54
- tmp = opts[:company_name]
55
- tmp = opts[:company] if tmp.nil? || tmp.empty?
57
+ tmp = user_data[:company_name]
58
+ tmp = user_data[:company] if tmp.nil? || tmp.empty?
56
59
  data[:companyName] = tmp if tmp && !tmp.empty?
57
60
 
58
61
  # Optional country
59
- tmp = opts[:country]
62
+ tmp = user_data[:country]
60
63
  data[:country] = tmp if tmp && !tmp.empty?
61
64
 
62
65
  # Optional phone number
63
- tmp = opts[:phone]
64
- tmp = opts[:phone_number] if tmp.nil? || tmp.empty?
66
+ tmp = user_data[:phone]
67
+ tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
65
68
  data[:phoneNumber] = tmp if tmp && !tmp.empty?
66
69
 
67
70
  # Optional position
68
- tmp = opts[:position]
71
+ tmp = user_data[:position]
69
72
  data[:position] = tmp if tmp && !tmp.empty?
70
73
 
71
74
  # Optional sso provider
72
- tmp = opts[:sso_provider]
75
+ tmp = user_data[:sso_provider]
73
76
  data['ssoProvider'] = tmp if tmp && !tmp.empty?
74
77
 
75
78
  # Optional timezone
76
- tmp = opts[:timezone]
79
+ tmp = user_data[:timezone]
77
80
  data[:timezone] = tmp if tmp && !tmp.empty?
78
81
 
79
82
  c = client(opts)
80
83
 
81
84
  # TODO: It will be nice if the API will return us user just newly created
82
- url = "/gdc/account/domains/#{opts[:domain]}/users"
83
- response = c.post(url, :accountSetting => data)
85
+ begin
86
+ url = "/gdc/account/domains/#{domain_name}/users"
87
+ response = c.post(url, :accountSetting => data)
88
+ rescue RestClient::BadRequest
89
+ raise GoodData::UserInDifferentDomainError, "User #{data[:login]} is already in different domain"
90
+ end
84
91
 
85
92
  url = response['uri']
86
93
  raw = c.get url
@@ -88,19 +95,82 @@ module GoodData
88
95
  # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
89
96
  raw['accountSetting']['links'] = {} unless raw['accountSetting']['links']
90
97
  raw['accountSetting']['links']['self'] = response['uri'] unless raw['accountSetting']['links']['self']
91
-
92
98
  c.create(GoodData::Profile, raw)
93
99
  end
94
100
 
101
+ def update_user(user_data, options = { client: GoodData.connection })
102
+ client = client(options)
103
+ user_data = user_data.to_hash
104
+ # generated_pass = rand(10E10).to_s
105
+ data = {
106
+ :firstName => user_data[:first_name] || 'FirstName',
107
+ :lastName => user_data[:last_name] || 'LastName',
108
+ :email => user_data[:email]
109
+ }
110
+
111
+ # Optional authentication modes
112
+ tmp = user_data[:authentication_modes]
113
+ if tmp
114
+ if tmp.is_a? Array
115
+ data[:authenticationModes] = tmp
116
+ elsif tmp.is_a? String
117
+ data[:authenticationModes] = [tmp]
118
+ end
119
+ end
120
+
121
+ # Optional company
122
+ tmp = user_data[:company_name]
123
+ tmp = user_data[:company] if tmp.nil? || tmp.empty?
124
+ data[:companyName] = tmp if tmp && !tmp.empty?
125
+
126
+ # Optional pass
127
+ tmp = user_data[:password]
128
+ tmp = user_data[:password] if tmp.nil? || tmp.empty?
129
+ data[:password] = tmp if tmp && !tmp.empty?
130
+ data[:verifyPassword] = tmp if tmp && !tmp.empty?
131
+
132
+ # Optional country
133
+ tmp = user_data[:country]
134
+ data[:country] = tmp if tmp && !tmp.empty?
135
+
136
+ # Optional phone number
137
+ tmp = user_data[:phone]
138
+ tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
139
+ data[:phoneNumber] = tmp if tmp && !tmp.empty?
140
+
141
+ # Optional position
142
+ tmp = user_data[:position]
143
+ data[:position] = tmp if tmp && !tmp.empty?
144
+
145
+ # Optional sso provider
146
+ tmp = user_data[:sso_provider]
147
+ data['ssoProvider'] = tmp if tmp && !tmp.empty?
148
+
149
+ # Optional timezone
150
+ tmp = user_data[:timezone]
151
+ data[:timezone] = tmp if tmp && !tmp.empty?
152
+
153
+ # TODO: It will be nice if the API will return us user just newly created
154
+ url = user_data.delete(:uri)
155
+ data.delete(:password) if client.user.uri == url
156
+ response = client.put(url, :accountSetting => data)
157
+
158
+ # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
159
+ response['accountSetting']['links'] = {} unless response['accountSetting']['links']
160
+ response['accountSetting']['links']['self'] = url unless response['accountSetting']['links']['self']
161
+ client.create(GoodData::Profile, response)
162
+ end
163
+
95
164
  # Finds user in domain by login
96
165
  #
97
166
  # @param domain [String] Domain name
98
167
  # @param login [String] User login
99
168
  # @return [GoodData::Profile] User profile
100
- def find_user_by_login(domain, login, opts = {})
169
+ def find_user_by_login(domain, login, opts = { :client => GoodData.connection, :project => GoodData.project })
101
170
  c = client(opts)
102
171
  escaped_login = CGI.escape(login)
103
- url = "/gdc/account/domains/#{domain}/users?login=#{escaped_login}"
172
+ domain = c.domain(domain)
173
+ url = "/gdc/account/domains/#{domain.name}/users?login=#{escaped_login}"
104
174
  tmp = c.get url
105
175
  items = tmp['accountSettings']['items'] if tmp['accountSettings']
106
176
  items && items.length > 0 ? c.factory.create(GoodData::Profile, items.first) : nil
@@ -123,6 +193,7 @@ module GoodData
123
193
  tmp['accountSettings']['items'].each do |account|
124
194
  result << client(opts).create(GoodData::Profile, account)
125
195
  end
196
+ break if opts[:limit] && result.length >= opts[:limit]
126
197
  uri = tmp['accountSettings']['paging']['next']
127
198
  end
128
199
 
@@ -133,57 +204,53 @@ module GoodData
133
204
  # @param [Array<GoodData::Membership>] list List of users
134
205
  # @param [String] default_domain_name Default domain name used when no specified in user
135
206
  # @return [Array<GoodData::User>] List of users created
136
- def users_create(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
207
+ def create_users(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
208
+ client = client(opts)
137
209
  default_domain_name = default_domain.respond_to?(:name) ? default_domain.name : default_domain
210
+ domain_obj = client.domain(default_domain_name)
138
211
  domains = {}
139
212
  list.map do |user|
140
- # TODO: Add user here
141
- domain_name = user.json['user']['content']['domain'] || default_domain_name
142
-
143
- # Lookup for domain in cache'
144
- domain = domains[domain_name]
145
-
146
- # Get domain info from REST, add to cache
147
- if domain.nil?
148
- d = GoodData::Domain[domain_name, opts]
149
- domain = {
150
- :domain => d,
151
- :users => d.users(opts)
152
- }
153
-
154
- domain[:users_map] = Hash[domain[:users].map { |u| [u.email, u] }]
155
- domains[domain_name] = domain
156
- end
157
-
158
- # Check if user exists in domain
159
- domain_user = domain[:users_map][user.email]
160
-
161
- # Create domain user if needed
162
- unless domain_user
163
- password = user.json['user']['content']['password']
164
-
165
- # Fill necessary user data
166
- user_data = {
167
- :login => user.login,
168
- :firstName => user.first_name,
169
- :lastName => user.last_name,
170
- :password => password,
171
- :verifyPassword => password,
172
- :email => user.login
173
- }
174
-
175
- tmp = user.json['user']['content']['sso_provider']
176
- user_data[:sso_provider] = tmp if tmp && !tmp.empty?
177
-
178
- tmp = user.json['user']['content']['authentication_modes']
179
- user_data[:authentication_modes] = tmp && !tmp.empty?
180
-
181
- # Add created user to cache
182
- domain_user = domain[:domain].add_user(opts.merge(user_data))
183
- domain[:users] << domain_user
184
- domain[:users_map][user.email] = domain_user
213
+ begin
214
+ user_data = user.to_hash
215
+ # TODO: Add user here
216
+ domain_name = user_data[:domain] || default_domain_name
217
+
218
+ # Lookup for domain in cache'
219
+ domain = domains[domain_name]
220
+
221
+ # Get domain info from REST, add to cache
222
+ if domain.nil?
223
+ domain = {
224
+ :domain => domain_obj,
225
+ :users => domain_obj.users
226
+ }
227
+
228
+ domain[:users_map] = Hash[domain[:users].map { |u| [u.login, u] }]
229
+ domains[domain_name] = domain
230
+ end
231
+
232
+ # Check if user exists in domain
233
+ domain_user = domain[:users_map][user_data[:login]]
234
+
235
+ # Create domain user if needed
236
+ if !domain_user
237
+ # Add created user to cache
238
+ domain_user = domain[:domain].add_user(user_data, opts)
239
+ domain[:users] << domain_user
240
+ domain[:users_map][domain_user.login] = domain_user
241
+ { type: :user_added_to_domain, user: domain_user }
242
+ else
243
+ # fields = [:firstName, :email]
244
+ diff = GoodData::Helpers.diff([domain_user.to_hash], [user_data], key: :login)
245
+ next if diff[:changed].empty?
246
+
247
+ domain_user = domain[:domain].update_user(domain_user.to_hash.merge(user_data.compact), opts)
248
+ domain[:users_map][domain_user.login] = domain_user
249
+ { type: :user_changed_in_domain, user: domain_user }
250
+ end
251
+ rescue RuntimeError => e
252
+ { type: :error, reason: e }
185
253
  end
186
- domain_user
187
254
  end
188
255
  end
189
256
  end
@@ -204,9 +271,34 @@ module GoodData
204
271
  # domain = GoodData::Domain['gooddata-tomas-korcak']
205
272
  # domain.add_user 'joe.doe@example', 'sup3rS3cr3tP4ssW0rtH'
206
273
  #
207
- def add_user(opts)
208
- opts[:domain] = name
209
- GoodData::Domain.add_user(opts)
274
+ def add_user(data, opts = {})
275
+ # data[:domain] = name
276
+ GoodData::Domain.add_user(data, name, { client: client }.merge(opts))
277
+ end
278
+
279
+ alias_method :create_user, :add_user
280
+
281
+ def create_users(list, options = {})
282
+ GoodData::Domain.create_users(list, name, { client: client }.merge(options))
283
+ end
284
+
285
+ # Gets user by its login or uri in various shapes
286
+ # It does not find by other information because that is not unique. If you want to search by name or email please
287
+ # use fuzzy_get_user.
288
+ #
289
+ # @param [String] name Name to look for
290
+ # @param [Array<GoodData::User>]user_list Optional cached list of users used for look-ups
291
+ # @return [GoodDta::Membership] User
292
+ def get_user(name, user_list = users)
293
+ return member(name) if name.instance_of?(GoodData::Membership)
294
+ return member(name) if name.instance_of?(GoodData::Profile)
295
+ name = name.is_a?(Hash) ? name[:login] || name[:uri] : name
296
+ return nil unless name
297
+ name.downcase!
298
+ user_list.find do |user|
299
+ user.uri && user.uri.downcase == name ||
300
+ user.login && user.login.downcase == name
301
+ end
210
302
  end
211
303
 
212
304
  # Finds user in domain by login
@@ -214,7 +306,43 @@ module GoodData
214
306
  # @param login [String] User login
215
307
  # @return [GoodData::Profile] User account settings
216
308
  def find_user_by_login(login)
217
- GoodData::Domain.find_user_by_login(name, login)
309
+ GoodData::Domain.find_user_by_login(self, login, client: client)
310
+ end
311
+
312
+ # Gets membership for profile specified
313
+ #
314
+ # @param [GoodData::Profile] profile - Profile to be checked
315
+ # @param [Array<GoodData::Profile>] list Optional list of members to check against
316
+ # @return [GoodData::Profile] Profile if found
317
+ def member(profile, list = members)
318
+ if profile.is_a? String
319
+ return list.find do |m|
320
+ m.uri == profile || m.login == profile
321
+ end
322
+ end
323
+ list.find { |m| m.login == profile.login }
324
+ end
325
+
326
+ # Checks if the profile is member of project
327
+ #
328
+ # @param [GoodData::Profile] profile - Profile to be checked
329
+ # @param [Array<GoodData::Membership>] list Optional list of members to check against
330
+ # @return [Boolean] true if is member else false
331
+ def member?(profile, list = members)
332
+ !member(profile, list).nil?
333
+ end
334
+
335
+ def members?(profiles, list = members)
336
+ profiles.map { |p| member?(p, list) }
337
+ end
338
+
339
+ # Update user in domain
340
+ #
341
+ # @param opts [Hash] Data of the user to be updated
342
+ # @return [Object] Raw response
343
+ #
344
+ def update_user(data, options = {})
345
+ GoodData::Domain.update_user(data, { client: client }.merge(options))
218
346
  end
219
347
 
220
348
  # List users in domain
@@ -234,9 +362,7 @@ module GoodData
234
362
  GoodData::Domain.users(name, opts.merge(client: client))
235
363
  end
236
364
 
237
- def users_create(list)
238
- GoodData::Domain.users_create(list, name)
239
- end
365
+ alias_method :members, :users
240
366
 
241
367
  private
242
368