Redefine user roles with their role in a study group

This commit is contained in:
Sebastian Serth
2022-09-20 16:19:04 +02:00
committed by Sebastian Serth
parent 04ed45ea73
commit 9c9f45ff77
12 changed files with 90 additions and 44 deletions

View File

@@ -16,13 +16,18 @@ class ApplicationController < ActionController::Base
rescue_from ActionController::InvalidAuthenticityToken, with: :render_csrf_error
def current_user
@current_user ||= ExternalUser.find_by(id: session[:external_user_id]) ||
login_from_session ||
login_from_other_sources ||
login_from_authentication_token ||
nil
@current_user ||= find_or_login_current_user&.store_current_study_group_id(session[:study_group_id])
end
def find_or_login_current_user
ExternalUser.find_by(id: session[:external_user_id]) ||
login_from_session ||
login_from_other_sources ||
login_from_authentication_token ||
nil
end
private :find_or_login_current_user
def require_user!
raise Pundit::NotAuthorizedError unless current_user
end

View File

@@ -181,11 +181,7 @@ module Lti
def set_current_user
@current_user = ExternalUser.find_or_create_by(consumer_id: @consumer.id, external_id: @provider.user_id)
external_role = external_user_role(@provider)
internal_role = @current_user.role
desired_role = internal_role == 'admin' ? internal_role : external_role
# Update user with new information but change the role only if he is no admin user
@current_user.update(email: external_user_email(@provider), name: external_user_name(@provider), role: desired_role)
@current_user.update(email: external_user_email(@provider), name: external_user_name(@provider))
end
private :set_current_user
@@ -199,8 +195,9 @@ module Lti
else
StudyGroup.find_or_create_by(external_id: @provider.resource_link_id, consumer: @consumer)
end
group.external_users << @current_user unless group.external_users.include? @current_user
group.save
study_group_membership = StudyGroupMembership.find_or_create_by(study_group: group, user: @current_user)
study_group_membership.update(role: external_user_role(@provider))
session[:study_group_id] = group.id
end

View File

@@ -32,7 +32,7 @@ class InternalUsersController < ApplicationController
def create
@user = InternalUser.new(internal_user_params)
@user.role = role_param if current_user.admin?
@user.platform_admin = platform_admin_param if current_user.admin?
authorize!
@user.send(:setup_activation)
create_and_respond(object: @user) do
@@ -77,10 +77,10 @@ class InternalUsersController < ApplicationController
end
private :internal_user_params
def role_param
params.require(:internal_user).permit(:role)[:role]
def platform_admin_param
params.require(:internal_user).permit(:platform_admin)[:platform_admin]
end
private :role_param
private :platform_admin_param
def new
@user = InternalUser.new
@@ -139,8 +139,7 @@ class InternalUsersController < ApplicationController
# the form by another user. Otherwise, the update might fail if an
# activation_token or password_reset_token is present
@user.validate_password = current_user == @user
@user.role = role_param if current_user.admin?
@user.platform_admin = platform_admin_param if current_user.admin?
update_and_respond(object: @user, params: internal_user_params)
end
end

View File

@@ -10,7 +10,6 @@ class InternalUser < User
validates :email, presence: true, uniqueness: true
validates :password, confirmation: true, if: -> { password_void? && validate_password? }, on: :update, presence: true
validate :password_strength, if: -> { password_void? && validate_password? }, on: :update
validates :role, inclusion: {in: ROLES}
def activated?
activation_state == 'active'
@@ -33,10 +32,6 @@ class InternalUser < User
errors.add(:password, :weak) if result.score < 4
end
def teacher?
role == 'teacher'
end
def displayname
name
end

View File

@@ -3,7 +3,7 @@
class User < ApplicationRecord
self.abstract_class = true
ROLES = %w[admin teacher learner].freeze
attr_reader :current_study_group_id
belongs_to :consumer
has_many :authentication_token, dependent: :destroy
@@ -26,9 +26,7 @@ class User < ApplicationRecord
joins(:study_group_memberships).where(study_group_memberships: {study_group_id: user.study_groups}) unless user.admin?
}
ROLES.each do |role|
define_method("#{role}?") { try(:role) == role }
end
validates :platform_admin, boolean_presence: true
def internal_user?
is_a?(InternalUser)
@@ -38,6 +36,30 @@ class User < ApplicationRecord
is_a?(ExternalUser)
end
def learner?
return true if current_study_group_id.nil?
@learner ||= current_study_group_membership.exists?(role: :learner) && !platform_admin?
end
def teacher?
@teacher ||= current_study_group_membership.exists?(role: :teacher) && !platform_admin?
end
def admin?
@admin ||= platform_admin?
end
def store_current_study_group_id(study_group_id)
@current_study_group_id = study_group_id
self
end
def current_study_group_membership
# We use `where(...).limit(1)` instead of `find_by(...)` to allow query chaining
study_group_memberships.where(study_group: current_study_group_id).limit(1)
end
def to_s
displayname
end