Newer
Older
Thesis_System / models / user.rb
@Fumichan Fumichan on 13 Nov 2019 2 KB First Commit
Bundler.require

class User <ActiveRecord::Base
  #データベースとの連携をmain.rbと同様に
  ActiveRecord::Base.configurations = YAML.load_file('./database.yml')
  ActiveRecord::Base.establish_connection(:development)

  #name,email,passwordは必須かつ一意
  validates :name, :email, :password_hash, :password_salt, presence: true ##idも後々
  validates :email, uniqueness: true ##idも後々
  validates :password_hash, confirmation: true

  #passwordのハッシュ化
  def encrypt_password(password)
    if password.present?
      #パスワードをハッシュ化するために用いるランダムなsaltを生成
      self.password_salt = BCrypt::Engine.generate_salt
      #ランダム生成したsaltを用いてパスワードをハッシュ化
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end

  def self.generate_rotp_key
    loop do
      rotp_key=ROTP::Base32.random
      check_key=self.find_by(rotp_key: rotp_key)
      if check_key==nil
        return rotp_key
      end
    end
  end

  def self.make_qrcode(email, key)
    totp = ROTP::TOTP.new(key)
    uri = totp.provisioning_uri(email)
    #logger.debug(uri)
    size = 12
    level = :h
    return RQRCode::QRCode.new(uri, size: size, level: level).as_png.resize(300, 300).to_data_url
  end

  def self.confirm_generated_rotp_key(key, otp)
    totp = ROTP::TOTP.new(key)
    return totp.verify(otp)
  end

  def self.confirm_otp(user_id, otp)
    user = self.find_by_id(user_id)
    totp = ROTP::TOTP.new(user.rotp_key)
    if totp.verify(otp)
      self.update(user_id, last_rotp_at: totp.verify(otp))
      return user
    else
      return nil
    end
  end

  def self.send_salt(email, salt)
    #現ログイン時userのemailを取得
    user = self.find_by(email: email)
    #logger.debug("hogehoge"+salt)
    #logger.debug(user)
    if user.blank?
      salt_dummy = BCrypt::Engine.generate_salt
      {nounce: salt_dummy, salt: salt}.to_json
    else
      {nounce: user.password_salt, salt: salt}.to_json
    end
  end

  #emailとpasswordで認証メソッド
  def self.authenticate(email, password, server_salt, client_salt)
    #現ログイン時userのemailを取得
    user = self.find_by(email: email)
    #ログインしたいuserのemailを取得できるか
    if user
      #logger.debug(client_salt)
      hmac = OpenSSL::HMAC.hexdigest('sha512', server_salt, user.password_hash)
      #logger.debug(hmac)
      hmac2 = OpenSSL::HMAC.hexdigest('sha512', client_salt, hmac)
      #打ち込まれたpasswordがログインしたいユーザーのハッシュと等しいか調査
      if password == hmac2
        return user
      end
    end
    return nil
  end

  def self.user_check(user_id)
    user = self.find_by(id: user_id)
    if user
      return user
    else
      return nil
    end
  end

end