freelensia

20210621 users.rb

Jun 21st, 2021
881
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # app/services/user_service/api/users.rb
  2.  
  3. module UserService::API
  4.   module Users
  5.  
  6.     module_function
  7.  
  8.     # TODO make people controller use this method too
  9.     # The challenge for that is the devise connections
  10.     def create_user(user_hash, community_id, invitation_id = nil)
  11.  
  12.       raise ArgumentError.new("Email #{user_hash[:email]} is already in use.") unless Email.email_available?(user_hash[:email], community_id)
  13.  
  14.       begin
  15.         username = generate_username(user_hash[:given_name], user_hash[:family_name], community_id)
  16.         locale = user_hash[:locale] || APP_CONFIG.default_locale # don't access config like this, require to be passed in in ctor
  17.  
  18.         person = Person.new(
  19.           given_name: user_hash[:given_name],
  20.           family_name: user_hash[:family_name],
  21.           password: user_hash[:password],
  22.           username: username,
  23.           locale: locale,
  24.           test_group_number: rand(1..4),
  25.           community_id: community_id)
  26.  
  27.         email = Email.new(person: person, address: user_hash[:email].downcase, send_notifications: true, community_id: community_id)
  28.  
  29.         person.emails << email
  30.         person.inherit_settings_from(Community.find(community_id)) if community_id
  31.  
  32.         ActiveRecord::Base.transaction do
  33.           person.save!
  34.           person.upsert_field_values_from_hash_params!({ first_name: user_hash[:given_name], last_name: user_hash[:family_name] }, community_id)
  35.           person.set_default_preferences
  36.  
  37.           user = from_model(person)
  38.  
  39.           # The first member will be made admin
  40.           MarketplaceService::API::Memberships.make_user_a_member_of_community(user[:id], community_id, invitation_id)
  41.  
  42.           email = Email.find_by_person_id!(user[:id])
  43.           community = Community.find(community_id)
  44.  
  45.           # send email confirmation (unless disabled for testing environment)
  46.           if APP_CONFIG.skip_email_confirmation
  47.             email.confirm!
  48.           else
  49.             Email.send_confirmation(email, community)
  50.           end
  51.  
  52.           Result::Success.new(user)
  53.         end
  54.       rescue StandardError
  55.         Result::Error.new("Failed to create a new user")
  56.       end
  57.     end
  58.  
  59.     def delete_user(id)
  60.       person = Person.where(id: id).first
  61.  
  62.       if person.nil?
  63.         Result::Error.new("Person with id '#{id}' not found")
  64.       else
  65.         # Delete personal information
  66.         person.update_attributes(
  67.           given_name: nil,
  68.           family_name: nil,
  69.           phone_number: nil,
  70.           description: nil,
  71.           facebook_id: nil,
  72.           # To ensure user can not log in anymore we have to:
  73.           #
  74.           # 1. Delete the password (Devise rejects login attempts if the password is empty)
  75.           # 2. Remove the emails (So that use can not reset the password)
  76.           encrypted_password: "",
  77.           deleted: true # Flag deleted
  78.         )
  79.  
  80.         # Delete emails
  81.         person.emails.destroy_all
  82.  
  83.         # Delete avatar
  84.         person.image.destroy
  85.         person.image.clear
  86.         person.image = nil
  87.         person.save(validate: false)
  88.  
  89.         # Delete follower relations, both way
  90.         person.follower_relationships.destroy_all
  91.         person.inverse_follower_relationships.destroy_all
  92.  
  93.         # Delete memberships
  94.         person.community_membership.update_attributes(status: "deleted_user")
  95.  
  96.         # Delte auth tokens
  97.         person.auth_tokens.destroy_all
  98.  
  99.         Result::Success.new
  100.       end
  101.     end
  102.  
  103.     def from_model(person)
  104.       hash = HashUtils.compact(
  105.         EntityUtils.model_to_hash(person).merge({
  106.             # This is a spot to modify hash contents if needed
  107.           }))
  108.       return UserService::API::DataTypes.create_user(hash)
  109.     end
  110.  
  111.     def username_from_fb_data(username:, given_name:, family_name:, community_id:)
  112.       base = Maybe(
  113.           Maybe(username)
  114.           .or_else(Maybe(given_name).strip.or_else("") + Maybe(family_name).strip()[0].or_else(""))
  115.         )
  116.         .to_url
  117.         .delete('-')
  118.         .or_else("fb_name_missing")[0...18]
  119.  
  120.       generate_username_from_base(base, community_id)
  121.     end
  122.  
  123.     def replace_with_default_locale(community_id:, locales:, default_locale:)
  124.       Person.where(community_id: community_id, locale: locales).update_all(locale: default_locale)
  125.     end
  126.  
  127.     # private
  128.  
  129.     def generate_username(given_name, family_name, community_id)
  130.       base = (given_name.strip + family_name.strip[0]).to_url.delete('-')[0...18]
  131.       generate_username_from_base(base, community_id)
  132.     end
  133.     private_class_method :generate_username
  134.  
  135.     def generate_username_from_base(base, community_id)
  136.       taken = fetch_taken_usernames(base, community_id)
  137.       reserved = Person.username_blacklist.concat(taken)
  138.       gen_free_name(base, reserved)
  139.     end
  140.     private_class_method :generate_username_from_base
  141.  
  142.     def fetch_taken_usernames(base, community_id)
  143.       Person.where("username LIKE :prefix AND community_id = :community_id",
  144.                    prefix: "#{base}%", community_id: community_id).pluck(:username)
  145.     end
  146.     private_class_method :fetch_taken_usernames
  147.  
  148.     def gen_free_name(base, reserved)
  149.       (1..100000).reduce([base, ""]) do |(base_name, postfix), next_postfix|
  150.         return (base_name + postfix) unless reserved.include?(base_name + postfix) || (base_name + postfix).length < 3
  151.         [base_name, next_postfix.to_s]
  152.       end
  153.     end
  154.     private_class_method :gen_free_name
  155.   end
  156. end
  157.  
RAW Paste Data