Class: GoodData::Domain

Inherits:
Rest::Resource show all
Defined in:
lib/gooddata/models/domain.rb

Constant Summary collapse

USER_LANGUAGES =
{
  'en-US' => 'English',
  'nl-NL' => 'Dutch',
  'es-ES' => 'Spanish',
  'pt-BR' => 'Portuguese/Brazil',
  'pt-PT' => 'Portuguese/Portugal',
  'fr-FR' => 'French',
  'de-DE' => 'German',
  'ja-JP' => 'Japanese'
}

Instance Attribute Summary collapse

Attributes inherited from Rest::Object

#client, #json, #project

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ObjId

#obj_id

Methods inherited from Rest::Object

client, default_client, #saved?

Methods included from Mixin::DataPropertyReader

#data_property_reader

Methods included from Mixin::DataPropertyWriter

#data_property_writer

Methods included from Mixin::MetaPropertyReader

#metadata_property_reader

Methods included from Mixin::MetaPropertyWriter

#metadata_property_writer

Methods included from Mixin::MetaGetter

#meta

Methods included from Mixin::DataGetter

#data

Methods included from Mixin::RootKeyGetter

#root_key

Methods included from Mixin::ContentGetter

#content

Constructor Details

#initialize(domain_name) ⇒ Domain

Returns a new instance of Domain.



303
304
305
# File 'lib/gooddata/models/domain.rb', line 303

def initialize(domain_name)
  @name = domain_name
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



15
16
17
# File 'lib/gooddata/models/domain.rb', line 15

def name
  @name
end

Class Method Details

.[](domain_name, options = { :client => GoodData.connection }) ⇒ String

Looks for domain

Parameters:

  • domain_name (String)

    Domain name

Returns:

  • (String)

    Domain object instance



33
34
35
36
37
38
# File 'lib/gooddata/models/domain.rb', line 33

def [](domain_name, options = { :client => GoodData.connection })
  return domain_name if domain_name.is_a?(Domain)
  c = client(options)
  fail "Using pseudo-id 'all' is not supported by GoodData::Domain" if domain_name.to_s == 'all'
  c.create(GoodData::Domain, domain_name)
end

.add_user(user_data, name = nil, opts = { :client => GoodData.connection }) ⇒ Object

Adds user to domain

Parameters:

  • domain (String)

    Domain name

  • login (String)

    Login of user to be invited

  • password (String)

    Default preset password

Returns:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/gooddata/models/domain.rb', line 46

def add_user(user_data, name = nil, opts = { :client => GoodData.connection })
  generated_pass = GoodData::Helpers::CryptoHelper.generate_password
  domain_name = name || user_data[:domain]
  user_data = user_data.to_hash
  data = {
    :login => user_data[:login] || user_data[:email],
    :firstName => user_data[:first_name] || 'FirstName',
    :lastName => user_data[:last_name] || 'LastName',
    :password => user_data[:password] || generated_pass,
    :verifyPassword => user_data[:password] || generated_pass,
    :email => user_data[:email] || user_data[:login],
    :language => ensure_user_language(user_data)
  }

  # Optional authentication modes
  tmp = user_data[:authentication_modes]
  if tmp
    if tmp.is_a? Array
      data[:authenticationModes] = tmp
    elsif tmp.is_a? String
      data[:authenticationModes] = [tmp]
    end
  end

  # Optional company
  tmp = user_data[:company_name]
  tmp = user_data[:company] if tmp.nil? || tmp.empty?
  data[:companyName] = tmp if tmp && !tmp.empty?

  # Optional country
  tmp = user_data[:country]
  data[:country] = tmp if tmp && !tmp.empty?

  # Optional phone number
  tmp = user_data[:phone]
  tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
  data[:phoneNumber] = tmp if tmp && !tmp.empty?

  # Optional position
  tmp = user_data[:position]
  data[:position] = tmp if tmp && !tmp.empty?

  # Optional sso provider
  tmp = user_data[:sso_provider]
  data['ssoProvider'] = tmp if tmp && !tmp.empty?

  # Optional timezone
  tmp = user_data[:timezone]
  data[:timezone] = tmp if tmp && !tmp.empty?

  # Optional ip whitelist
  tmp = user_data[:ip_whitelist]
  data[:ipWhitelist] = tmp if tmp

  c = client(opts)

  # TODO: It will be nice if the API will return us user just newly created
  begin
    url = "/gdc/account/domains/#{domain_name}/users"
    response = c.post(url, :accountSetting => data)
  rescue RestClient::BadRequest => e
    error = MultiJson.load(e.response)
    error_type = GoodData::Helpers.get_path(error, %w(error errorClass))
    case error_type
    when 'com.gooddata.webapp.service.userprovisioning.LoginNameAlreadyRegisteredException'
      u = Domain.(domain_name, data[:login])
      if u
        response = { 'uri' => u.uri }
      else
        raise GoodData::UserInDifferentDomainError, "User #{data[:login]} is already in different domain"
      end
    when 'com.gooddata.json.validator.exception.MalformedMessageException'
      raise GoodData::MalformedUserError, "User #{data[:login]} is malformed. The message from API is #{GoodData::Helpers.interpolate_error_message(error)}"
    else
      raise GoodData::Helpers.interpolate_error_message(error)
    end
  end

  url = response['uri']
  raw = c.get url

  # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
  raw['accountSetting']['links'] = {} unless raw['accountSetting']['links']
  raw['accountSetting']['links']['self'] = response['uri'] unless raw['accountSetting']['links']['self']
  c.create(GoodData::Profile, raw)
end

.create_users(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project }) ⇒ Array<GoodData::User>

Create users specified in list

Parameters:

  • list (Array<GoodData::Membership>)

    List of users

  • default_domain_name (String)

    Default domain name used when no specified in user

Returns:

  • (Array<GoodData::User>)

    List of users created



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/gooddata/models/domain.rb', line 251

def create_users(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
  default_domain_name = default_domain.respond_to?(:name) ? default_domain.name : default_domain
  domain = client.domain(default_domain_name)

  # Prepare cache for domain users
  domain_users_cache = Hash[domain.users.map { |u| [u..downcase, u] }]

  list.pmapcat do |user|
    begin
      user_data = user.to_hash.tap { |uh| uh[:login].downcase! }
      domain_user = domain_users_cache[user_data[:login]]
       = user_data[:login]
      if !domain_user
        added_user = domain.add_user(user_data, opts)
        GoodData.logger.info("Added new user=#{} to domain=#{default_domain_name}.")
        [{ type: :successful, :action => :user_added_to_domain, user: added_user }]
      else
        domain_user_data = domain_user.to_hash
        fields_to_check = opts[:fields_to_check] || user_data.keys
        diff = GoodData::Helpers.diff([domain_user.to_hash], [user_data], key: :login, fields: fields_to_check)
        next [] if diff[:changed].empty?
        updated_user = domain.update_user(domain_user.to_hash.merge(user_data.compact), opts)
        GoodData.logger.debug "Updated user=#{} from old properties \
(email=#{domain_user_data[:email]}, sso_provider=#{domain_user_data[:sso_provider]}) \
to new properties (email=#{user_data[:email]}, sso_provider=#{user_data[:sso_provider]}) in domain=#{default_domain_name}."
        [{ type: :successful, :action => :user_changed_in_domain, user: updated_user }]
      end
    rescue RuntimeError => e
      if !domain_user
        GoodData.logger.error("Failed to add user=#{} to domain=#{default_domain_name}. Error: #{e.message}")
      else
        GoodData.logger.error("Failed to update user=#{} in domain=#{default_domain_name}. Error: #{e.message}")
      end
      [{ type: :failed, :user => user, message: e }]
    end
  end
end

.find_user_by_login(domain, login, opts = { :client => GoodData.connection, :project => GoodData.project }) ⇒ GoodData::Profile

Finds user in domain by login

Parameters:

  • domain (String)

    Domain name

  • login (String)

    User login

Returns:



202
203
204
205
206
207
208
209
210
211
# File 'lib/gooddata/models/domain.rb', line 202

def (domain, , opts = { :client => GoodData.connection, :project => GoodData.project })
  c = client(opts)
   = CGI.escape()
  domain = c.domain(domain)
  GoodData.logger.warn("Retrieving particular user \"#{.inspect}\" from domain #{domain.name}")
  url = "#{domain.uri}/users?login=#{}"
  tmp = c.get url
  items = tmp['accountSettings']['items'] if tmp['accountSettings']
  items && !items.empty? ? c.factory.create(GoodData::Profile, items.first) : nil
end

.update_user(user_data, options = { client: GoodData.connection }) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/gooddata/models/domain.rb', line 133

def update_user(user_data, options = { client: GoodData.connection })
  user_data = user_data.to_hash if user_data.is_a?(GoodData::Profile)
  client = client(options)
  user_data = user_data.to_hash
  data = {
    :firstName => user_data[:first_name] || 'FirstName',
    :lastName => user_data[:last_name] || 'LastName',
    :email => user_data[:email],
    :language => ensure_user_language(user_data)
  }

  # Optional authentication modes
  tmp = user_data[:authentication_modes]
  if tmp
    if tmp.is_a? Array
      data[:authenticationModes] = tmp
    elsif tmp.is_a? String
      data[:authenticationModes] = [tmp]
    end
  end

  # Optional company
  tmp = user_data[:company_name]
  tmp = user_data[:company] if tmp.nil? || tmp.empty?
  data[:companyName] = tmp if tmp && !tmp.empty?

  # Optional pass
  tmp = user_data[:password]
  tmp = user_data[:password] if tmp.nil? || tmp.empty?
  data[:password] = tmp if tmp && !tmp.empty?
  data[:verifyPassword] = tmp if tmp && !tmp.empty?

  # Optional country
  tmp = user_data[:country]
  data[:country] = tmp if tmp && !tmp.empty?

  # Optional phone number
  tmp = user_data[:phone]
  tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
  data[:phoneNumber] = tmp if tmp && !tmp.empty?

  # Optional position
  tmp = user_data[:position]
  data[:position] = tmp if tmp && !tmp.empty?

  # Optional sso provider
  tmp = user_data[:sso_provider]
  data['ssoProvider'] = tmp if tmp

  # Optional timezone
  tmp = user_data[:timezone]
  data[:timezone] = tmp if tmp && !tmp.empty?

  # TODO: It will be nice if the API will return us user just newly created
  url = user_data.delete(:uri)
  data.delete(:password) if client.user.uri == url
  response = client.put(url, :accountSetting => data)

  # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
  response['accountSetting']['links'] = {} unless response['accountSetting']['links']
  response['accountSetting']['links']['self'] = url unless response['accountSetting']['links']['self']
  client.create(GoodData::Profile, response)
end

.users(domain, id = :all, opts = {}) ⇒ Object

Returns list of users for domain specified TODO: Review opts[:limit] functionality

Parameters:

  • domain (String)

    Domain to list the users for

  • opts (Hash) (defaults to: {})

    Options.

Options Hash (opts):

  • :offset (Number)

    The subject

  • :limit (Number)

    From address



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/gooddata/models/domain.rb', line 219

def users(domain, id = :all, opts = {})
  client = client(opts)
  domain = client.domain(domain)
  if id == :all
    GoodData.logger.warn("Retrieving all users from domain #{domain.name}")
    all_users = []
    page_limit = opts[:page_limit] || 1000
    offset = opts[:offset] || 0
    loop do
      begin
        tmp = client(opts).get("#{domain.uri}/users", params: { offset: offset, limit: page_limit })
      end

      tmp['accountSettings']['items'].each do |user_data|
        user = client.create(GoodData::Profile, user_data)
        all_users << user if user
      end
      break if tmp['accountSettings']['items'].count < page_limit

      offset += page_limit
    end

    all_users
  else
    (domain, id, opts)
  end
end

Instance Method Details

#add_user(data, opts = {}) ⇒ Object Also known as: create_user

Adds user to domain

Example

GoodData.connect '[email protected]' 'your-password' domain = project.domain('domain-name') domain.add_user 'joe.doe@example', 'sup3rS3cr3tP4ssW0rtH'

Parameters:

  • login (String)

    Login of user to be invited

  • password (String)

    Default preset password

Returns:



319
320
321
322
# File 'lib/gooddata/models/domain.rb', line 319

def add_user(data, opts = {})
  # data[:domain] = name
  GoodData::Domain.add_user(data, name, { client: client }.merge(opts))
end

#clients(id = :all, data_product = nil) ⇒ Object

Returns all the clients defined in all segments defined in domain. Alternatively id of a client can be provided in which case it returns just that client if it exists.

Parameters:

  • id (String) (defaults to: :all)

    Id of client that you are looking for

  • data_product (DataProduct) (defaults to: nil)

    data product object in which the clients are located

Returns:



332
333
334
# File 'lib/gooddata/models/domain.rb', line 332

def clients(id = :all, data_product = nil)
  GoodData::Client[id, data_product: data_product, domain: self]
end

#create_data_product(data) ⇒ Object



346
347
348
349
# File 'lib/gooddata/models/domain.rb', line 346

def create_data_product(data)
  data_product = GoodData::DataProduct.create(data, domain: self, client: client)
  data_product.save
end

#create_segment(data) ⇒ GoodData::Segment

Creates new segment in current domain from parameters passed

Parameters:

  • data (Hash)

    Data for segment namely :segment_id and :master_project is accepted. Master_project can be given as either a PID or a Project instance

Returns:



359
360
361
362
# File 'lib/gooddata/models/domain.rb', line 359

def create_segment(data)
  segment = GoodData::Segment.create(data, domain: self, client: client)
  segment.save
end

#create_users(list, options = {}) ⇒ Object



338
339
340
# File 'lib/gooddata/models/domain.rb', line 338

def create_users(list, options = {})
  GoodData::Domain.create_users(list, name, { client: client }.merge(options))
end

#data_products(id = :all) ⇒ Object



342
343
344
# File 'lib/gooddata/models/domain.rb', line 342

def data_products(id = :all)
  GoodData::DataProduct[id, domain: self]
end

#find_user_by_login(login) ⇒ GoodData::Profile

Finds user in domain by login

Parameters:

  • login (String)

    User login

Returns:



390
391
392
# File 'lib/gooddata/models/domain.rb', line 390

def ()
  GoodData::Domain.(self, , client: client)
end

#get_user(name, user_list = users) ⇒ GoodDta::Membership

Gets user by its login or uri in various shapes It does not find by other information because that is not unique. If you want to search by name or email please use fuzzy_get_user.

Optional cached list of users used for look-ups. WARNING: If not specified, in the worst case the method gets all users from the domain!

Parameters:

  • name (String)

    Name to look for

  • user_list (Array<GoodData::User>) (defaults to: users)

Returns:

  • (GoodDta::Membership)

    User



374
375
376
377
378
379
380
381
382
383
384
# File 'lib/gooddata/models/domain.rb', line 374

def get_user(name, user_list = users)
  return member(name, user_list) if name.instance_of?(GoodData::Membership)
  return member(name, user_list) if name.instance_of?(GoodData::Profile)
  name = name.is_a?(Hash) ? name[:login] || name[:uri] : name
  return nil unless name
  name.downcase!
  user_list.find do |user|
    user.uri && user.uri.downcase == name ||
      user. && user..downcase == name
  end
end

#member(profile, list = members) ⇒ GoodData::Profile

Gets membership for profile specified

Parameters:

Returns:



399
400
401
402
403
404
405
406
# File 'lib/gooddata/models/domain.rb', line 399

def member(profile, list = members)
  if profile.is_a? String
    return list.find do |m|
      m.uri == profile || m. == profile
    end
  end
  list.find { |m| m. == profile. }
end

#member?(profile, list = members) ⇒ Boolean

Checks if the profile is member of project

Parameters:

Returns:

  • (Boolean)

    true if is member else false



413
414
415
# File 'lib/gooddata/models/domain.rb', line 413

def member?(profile, list = members)
  !member(profile, list).nil?
end

#members?(profiles, list = members) ⇒ Boolean

Returns:

  • (Boolean)


417
418
419
# File 'lib/gooddata/models/domain.rb', line 417

def members?(profiles, list = members)
  profiles.map { |p| member?(p, list) }
end

#provision_client_projects(segments = nil) ⇒ Enumerator

Runs async process that walks through segments and provisions projects if necessary.

Returns:

  • (Enumerator)

    Returns Enumerator of results



438
439
440
441
442
443
444
# File 'lib/gooddata/models/domain.rb', line 438

def provision_client_projects(segments = nil)
  segments = segments.is_a?(Array) ? segments : [segments]
  segments.each do |segment_id|
    segment = segments(segment_id)
    segment.provision_client_projects
  end
end

#segments(id = :all, data_product = nil) ⇒ Object



351
352
353
# File 'lib/gooddata/models/domain.rb', line 351

def segments(id = :all, data_product = nil)
  GoodData::Segment[id, data_product: data_product, domain: self]
end

#segments_uriString

Returns uri for segments on the domain. This will be removed soon. It is here that for segments the "account" portion of the URI was removed. And not for the rest

Returns:

  • (String)

    Uri of the segments



424
425
426
# File 'lib/gooddata/models/domain.rb', line 424

def segments_uri
  "/gdc/domains/#{name}"
end

#synchronize_clientsArray

Calls Segment#synchronize_clients on all segments and concatenates the results

Returns:

  • (Array)

    Returns array of results



431
432
433
# File 'lib/gooddata/models/domain.rb', line 431

def synchronize_clients
  segments.flat_map(&:synchronize_clients)
end

#update_clients(data, options = {}) ⇒ Object



458
459
460
461
462
463
464
465
# File 'lib/gooddata/models/domain.rb', line 458

def update_clients(data, options = {})
  results = []
  data.group_by(&:data_product_id).each do |data_product_id, client_update_data|
    data_product = data_products(data_product_id)
    results.concat data_product.update_clients(client_update_data, options)
  end
  results
end

#update_clients_settings(data) ⇒ Object Also known as: add_clients_settings



446
447
448
449
450
451
452
453
454
455
# File 'lib/gooddata/models/domain.rb', line 446

def update_clients_settings(data)
  data.each do |datum|
    client_id = datum[:id]
    settings = datum[:settings]
    settings.each do |setting|
      GoodData::Client.update_setting(setting[:name], setting[:value], domain: self, client_id: client_id, data_product_id: datum[:data_product_id])
    end
  end
  nil
end

#update_user(data, options = {}) ⇒ Object

Update user in domain

Parameters:

  • opts (Hash)

    Data of the user to be updated

Returns:



472
473
474
# File 'lib/gooddata/models/domain.rb', line 472

def update_user(data, options = {})
  GoodData::Domain.update_user(data, { client: client }.merge(options))
end

#uriString

Returns uri for the domain.

Returns:

  • (String)

    Uri of the segments



498
499
500
# File 'lib/gooddata/models/domain.rb', line 498

def uri
  "/gdc/account/domains/#{name}"
end

#users(id = :all, opts = {}) ⇒ Array<GoodData::Profile> Also known as: members

List users in domain

Example

GoodData.connect '[email protected]' 'your-password' domain = GoodData::Domain['gooddata-tomas-korcak'] pp domain.users

Parameters:

  • opts (Hash) (defaults to: {})

    Additional user listing options.

Options Hash (opts):

  • :offset (Number)

    Offset to start listing from

  • :limit (Number)

    Limit of users to be listed

Returns:



489
490
491
# File 'lib/gooddata/models/domain.rb', line 489

def users(id = :all, opts = {})
  GoodData::Domain.users(name, id, opts.merge(client: client))
end