about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2020-08-30 16:13:08 +0200
committerThibaut Girka <thib@sitedethib.com>2020-08-30 16:13:08 +0200
commit8c3c27bf063d648823da39a206be3efd285611ad (patch)
treec78c0bed2bab5ed64a7dfd546b91b21600947112 /app/models
parent30632adf9eda6d83a9b4269f23f11ced5e09cd93 (diff)
parent52157fdcba0837c782edbfd240be07cabc551de9 (diff)
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts:
- `app/controllers/accounts_controller.rb`:
  Upstream change too close to a glitch-soc change related to
  instance-local toots. Merged upstream changes.
- `app/services/fan_out_on_write_service.rb`:
  Minor conflict due to glitch-soc's handling of Direct Messages,
  merged upstream changes.
- `yarn.lock`:
  Not really a conflict, caused by glitch-soc-only dependencies
  being textually too close to updated upstream dependencies.
  Merged upstream changes.
Diffstat (limited to 'app/models')
-rw-r--r--app/models/media_attachment.rb2
-rw-r--r--app/models/user.rb18
-rw-r--r--app/models/webauthn_credential.rb22
3 files changed, 41 insertions, 1 deletions
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index cfdd95b22..cc81b648c 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -338,7 +338,7 @@ class MediaAttachment < ApplicationRecord
 
     raise Mastodon::StreamValidationError, 'Video has no video stream' if movie.width.nil? || movie.frame_rate.nil?
     raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT
-    raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.to_i}fps videos are not supported" if movie.frame_rate > MAX_VIDEO_FRAME_RATE
+    raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.floor}fps videos are not supported" if movie.frame_rate.floor > MAX_VIDEO_FRAME_RATE
   end
 
   def set_meta
diff --git a/app/models/user.rb b/app/models/user.rb
index a05d98d88..77b50d966 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -40,6 +40,7 @@
 #  approved                  :boolean          default(TRUE), not null
 #  sign_in_token             :string
 #  sign_in_token_sent_at     :datetime
+#  webauthn_id               :string
 #
 
 class User < ApplicationRecord
@@ -77,6 +78,7 @@ class User < ApplicationRecord
   has_many :backups, inverse_of: :user
   has_many :invites, inverse_of: :user
   has_many :markers, inverse_of: :user, dependent: :destroy
+  has_many :webauthn_credentials, dependent: :destroy
 
   has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy
   accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? }
@@ -198,9 +200,25 @@ class User < ApplicationRecord
     prepare_returning_user!
   end
 
+  def otp_enabled?
+    otp_required_for_login
+  end
+
+  def webauthn_enabled?
+    webauthn_credentials.any?
+  end
+
+  def two_factor_enabled?
+    otp_required_for_login? || webauthn_credentials.any?
+  end
+
   def disable_two_factor!
     self.otp_required_for_login = false
+    self.otp_secret = nil
     otp_backup_codes&.clear
+
+    webauthn_credentials.destroy_all if webauthn_enabled?
+
     save!
   end
 
diff --git a/app/models/webauthn_credential.rb b/app/models/webauthn_credential.rb
new file mode 100644
index 000000000..4129ce539
--- /dev/null
+++ b/app/models/webauthn_credential.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: webauthn_credentials
+#
+#  id          :bigint(8)        not null, primary key
+#  external_id :string           not null
+#  public_key  :string           not null
+#  nickname    :string           not null
+#  sign_count  :bigint(8)        default(0), not null
+#  user_id     :bigint(8)
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#
+
+class WebauthnCredential < ApplicationRecord
+  validates :external_id, :public_key, :nickname, :sign_count, presence: true
+  validates :external_id, uniqueness: true
+  validates :nickname, uniqueness: { scope: :user_id }
+  validates :sign_count,
+            numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 2**32 - 1 }
+end