about summary refs log tree commit diff
path: root/app/models/concerns
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns')
-rw-r--r--app/models/concerns/ldap_authenticable.rb25
-rw-r--r--app/models/concerns/omniauthable.rb2
-rw-r--r--app/models/concerns/pam_authenticable.rb68
-rw-r--r--app/models/concerns/user_roles.rb54
4 files changed, 149 insertions, 0 deletions
diff --git a/app/models/concerns/ldap_authenticable.rb b/app/models/concerns/ldap_authenticable.rb
new file mode 100644
index 000000000..e1b5e3832
--- /dev/null
+++ b/app/models/concerns/ldap_authenticable.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module LdapAuthenticable
+  extend ActiveSupport::Concern
+
+  def ldap_setup(_attributes)
+    self.confirmed_at = Time.now.utc
+    self.admin        = false
+
+    save!
+  end
+
+  class_methods do
+    def ldap_get_user(attributes = {})
+      resource = joins(:account).find_by(accounts: { username: attributes[Devise.ldap_uid.to_sym].first })
+
+      if resource.blank?
+        resource = new(email: attributes[:mail].first, agreement: true, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
+        resource.ldap_setup(attributes)
+      end
+
+      resource
+    end
+  end
+end
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 4dd2e9383..1b28b8162 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -7,6 +7,8 @@ module Omniauthable
   TEMP_EMAIL_REGEX = /\Achange@me/
 
   included do
+    devise :omniauthable
+
     def omniauth_providers
       Devise.omniauth_configs.keys
     end
diff --git a/app/models/concerns/pam_authenticable.rb b/app/models/concerns/pam_authenticable.rb
new file mode 100644
index 000000000..2f651c1a3
--- /dev/null
+++ b/app/models/concerns/pam_authenticable.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module PamAuthenticable
+  extend ActiveSupport::Concern
+
+  included do
+    devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
+
+    def pam_conflict(_attributes)
+      # Block pam login tries on traditional account
+    end
+
+    def pam_conflict?
+      if Devise.pam_authentication
+        encrypted_password.present? && pam_managed_user?
+      else
+        false
+      end
+    end
+
+    def pam_get_name
+      if account.present?
+        account.username
+      else
+        super
+      end
+    end
+
+    def pam_setup(_attributes)
+      account = Account.new(username: pam_get_name)
+      account.save!(validate: false)
+
+      self.email        = "#{account.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
+      self.confirmed_at = Time.now.utc
+      self.admin        = false
+      self.account      = account
+
+      account.destroy! unless save
+    end
+
+    def self.pam_get_user(attributes = {})
+      return nil unless attributes[:email]
+
+      resource = begin
+        if Devise.check_at_sign && !attributes[:email].index('@')
+          joins(:account).find_by(accounts: { username: attributes[:email] })
+        else
+          find_by(email: attributes[:email])
+        end
+      end
+
+      if resource.nil?
+        resource = new(email: attributes[:email], agreement: true)
+
+        if Devise.check_at_sign && !resource[:email].index('@')
+          resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
+          resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
+        end
+      end
+
+      resource
+    end
+
+    def self.authenticate_with_pam(attributes = {})
+      super if Devise.pam_authentication
+    end
+  end
+end
diff --git a/app/models/concerns/user_roles.rb b/app/models/concerns/user_roles.rb
new file mode 100644
index 000000000..58dffdc46
--- /dev/null
+++ b/app/models/concerns/user_roles.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module UserRoles
+  extend ActiveSupport::Concern
+
+  included do
+    scope :admins, -> { where(admin: true) }
+    scope :moderators, -> { where(moderator: true) }
+    scope :staff, -> { admins.or(moderators) }
+  end
+
+  def staff?
+    admin? || moderator?
+  end
+
+  def role
+    if admin?
+      'admin'
+    elsif moderator?
+      'moderator'
+    else
+      'user'
+    end
+  end
+
+  def role?(role)
+    case role
+    when 'user'
+      true
+    when 'moderator'
+      staff?
+    when 'admin'
+      admin?
+    else
+      false
+    end
+  end
+
+  def promote!
+    if moderator?
+      update!(moderator: false, admin: true)
+    elsif !admin?
+      update!(moderator: true)
+    end
+  end
+
+  def demote!
+    if admin?
+      update!(admin: false, moderator: true)
+    elsif moderator?
+      update!(moderator: false)
+    end
+  end
+end