Method: GoodData::Project#import_users

Defined in:
lib/gooddata/models/project.rb

#import_users(new_users, options = {}) ⇒ Object

Imports users



1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
# File 'lib/gooddata/models/project.rb', line 1854

def import_users(new_users, options = {})
  role_list = roles
  users_list = users

  GoodData.logger.warn("Importing users to project (#{pid})")
  new_users = new_users.map { |x| ((x.is_a?(Hash) && x[:user] && x[:user].to_hash.merge(role: x[:role])) || x.to_hash).tap { |u| u[:login].downcase! } }
  # First check that if groups are provided we have them set up
  user_groups_cache, change_groups = check_groups(new_users.map(&:to_hash).flat_map { |u| u[:user_group] || [] }.uniq, options[:user_groups_cache], options)

  unless change_groups.empty?
    new_users.each do |user|
      user[:user_group].map! { |e| change_groups[e].nil? ? e : change_groups[e] }
    end
  end

  whitelisted_new_users, whitelisted_users = whitelist_users(new_users.map(&:to_hash), users_list, options[:whitelists])

  # conform the role on list of new users so we can diff them with the users coming from the project
  diffable_new_with_default_role = whitelisted_new_users.map do |u|
    u[:role] = Array(u[:role] || u[:roles] || 'readOnlyUser')
    u
  end

  intermediate_new = diffable_new_with_default_role.map do |u|
    u[:role] = u[:role].map do |r|
      role = get_role(r, role_list)
      role ? role.uri : r
    end

    u[:role_title] = u[:role].map do |r|
      role = get_role(r, role_list)
      role ? role.title : r
    end

    if u[:role].all?(&:nil?)
      u[:type] = :error
      u[:reason] = 'Invalid role(s) specified'
    else
      u[:type] = :ok
    end

    u[:status] = 'ENABLED'
    u
  end

  intermediate_new_by_type = intermediate_new.group_by { |i| i[:type] }
  diffable_new = intermediate_new_by_type[:ok] || []

  # Diff users. Only login and role is important for the diff
  diff = GoodData::Helpers.diff(whitelisted_users, diffable_new, key: :login, fields: [:login, :role, :status])
  diff_results = diff.flat_map do |operation, users|
    if operation == :changed
      users.map { |u| u[:new_obj].merge(operation: operation) }
    else
      users.map { |u| u.merge(operation: operation) }
    end
  end
  diff_results = diff_results.map do |u|
    u[:login_uri] =  + u[:login]
    u
  end
  return diff_results if options[:dry_run]

  # Create new users
  results = []
  GoodData.logger.warn("Creating #{diff[:added].count} users in project (#{pid})")
  to_create = diff[:added].map { |x| { user: x, role: x[:role] } }
  created_users_result = create_users(to_create, roles: role_list, project_users: whitelisted_users)
  @log_formatter.log_created_users(created_users_result, diff[:added])
  results.concat(created_users_result)
  send_mail_to_new_users(diff[:added], options[:email_options]) if options[:email_options] && !options[:email_options].empty? && !diff[:added].empty?

  # # Update existing users
  GoodData.logger.warn("Updating #{diff[:changed].count} users in project (#{pid})")
  to_update = diff[:changed].map { |x| { user: x[:new_obj], role: x[:new_obj][:role] || x[:new_obj][:roles] } }
  updated_users_result = set_users_roles(to_update, roles: role_list, project_users: whitelisted_users)
  @log_formatter.log_updated_users(updated_users_result, diff[:changed], role_list)
  results.concat(updated_users_result)

  unless options[:do_not_touch_users_that_are_not_mentioned]
    # Remove old users
    to_disable = diff[:removed].reject { |user| user[:status] == 'DISABLED' || user[:status] == :disabled }
    GoodData.logger.warn("Disabling #{to_disable.count} users from project (#{pid})")
    disabled_users_result = disable_users(to_disable, roles: role_list, project_users: whitelisted_users)
    @log_formatter.log_disabled_users(disabled_users_result)
    results.concat(disabled_users_result)

    # Remove old users completely
    if options[:remove_users_from_project]
      to_remove = (to_disable + users(disabled: true).to_a).map(&:to_hash).uniq do |user|
        user[:uri]
      end
      GoodData.logger.warn("Removing #{to_remove.count} users from project (#{pid})")
      removed_users_result = remove_users(to_remove)
      @log_formatter.log_removed_users(removed_users_result)
      results.concat(removed_users_result)
    end
  end

  # reassign to groups
  removal_user_group_members = []
  mappings = new_users.map(&:to_hash).flat_map do |user|
    removal_user_group_members << user[:login] if user[:user_group]&.empty?
    groups = user[:user_group] || []
    groups.map { |g| [user[:login], g] }
  end

  unless mappings.empty?
    users_lookup = 
    mappings.group_by { |_, g| g }.each do |g, mapping|
      remote_users = mapping.map { |user, _| user }.map { || users_lookup[] && users_lookup[].uri }.reject(&:nil?)
      GoodData.logger.info("Assigning users #{remote_users} to group #{g}")
      next if remote_users.empty?
      existing_group = user_groups(g)
      if existing_group.nil?
        GoodData.logger.warn("Group #{g} not found!!!")
      else
        existing_group.set_members(remote_users)
      end
    end
    mentioned_groups = mappings.map(&:last).uniq
    groups_to_cleanup = user_groups_cache.reject { |g| mentioned_groups.include?(g.name) }

    # clean all groups not mentioned with exception of whitelisted users
    groups_to_cleanup.each do |g|
      g.set_members(whitelist_users(g.members.map(&:to_hash), [], options[:whitelists], :include).first.map { |x| x[:uri] })
    end
  end

  remove_member_from_group(users_lookup, removal_user_group_members, user_groups_cache)
  GoodData::Helpers.join(results, diff_results, [:user], [:login_uri])
end