Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/controllers/exam_questions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def create

if @exam_question.save
if @exam_question.exam.questions.size > 1
render partial: 'question', locals: { question: @exam_question.question, exam_question: @exam_question, exam: @exam_question.exam, hide_columns: false, can_see_preview: true }
render partial: 'question', locals: { question: @exam_question.question, exam_question: @exam_question, exam: @exam_question.exam, hide_columns: false, can_see_preview: true, can_show_order: true }
else
redirect_to exam_questions_path(exam_id: @exam_question.exam_id, allocation_tags_ids: at_ids)
end
Expand Down Expand Up @@ -94,7 +94,7 @@ def update
QuestionText.find(params['question_texts_id']).destroy
end
end
render partial: 'question', locals: { question: @exam_question.question, exam_question: @exam_question, exam: @exam_question.exam, hide_columns: false, can_see_preview: true }
render partial: 'question', locals: { question: @exam_question.question, exam_question: @exam_question, exam: @exam_question.exam, hide_columns: false, can_see_preview: true, can_show_order: true }
else
@errors = []
@exam_question.errors.each do |attribute, erro|
Expand Down Expand Up @@ -136,6 +136,8 @@ def publish
ExamQuestion.where(id: ids).each do |exam_question|
exam_question.question.can_change_status?
exam_question.question.update_attributes status: true

log(exam_question.exam, "question: #{exam_question.question_id} [publish], exam: #{exam_question.exam_id}, #{exam_question.log_description}", LogAction::TYPE[:update]) rescue nil
end
end

Expand Down
28 changes: 25 additions & 3 deletions app/controllers/exams_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ def open

@total_time = (@last_attempt.try(:complete) ? 0 : @last_attempt.try(:get_total_time)) || 0

if params[:page].nil? && @last_attempt.total_time == 0
log(@exam, "exam_id: #{@exam&.id}#{@exam.attempts > 1 ? ", attempt: #{@exam&.exam_user_attempts&.length}" : ''}, description: \"Prova iniciada!\"", LogAction::TYPE[:update])
end

SysLog::Actions.log_info do
"[PROVA] Abriu prova pagina #{params[:page]} exam_id #{@exam.try(:id)} user_id=#{current_user.try(:id)} last_attempt: #{@last_attempt.as_json} - total_time #{@total_time} - exam_user_attempt #{params[:exam_user_attempt_id]}"
end
Expand Down Expand Up @@ -266,9 +270,12 @@ def complete
SysLog::Actions.log_info do
"[PROVA] Abriu método de finalizar prova #{params[:id]} user_id=#{current_user.try(:id)} acu #{acu.as_json} - SUCESSO"
end

user_session[:blocking_content] = Exam.verify_blocking_content(current_user.id)
render_exam_success_json('finish')
#redirect_to exams_path, notice: t('finish', scope: 'exams.success')

log(exam, "exam_id: #{exam&.id}#{exam.attempts > 1 ? ", attempt: #{exam&.exam_user_attempts&.length}" : ''}, description: \"Prova finalizada!\"", LogAction::TYPE[:update])
#render_exam_success_json('finish')
redirect_to exams_path, notice: t('finish', scope: 'exams.success')
end
end
rescue => error
Expand Down Expand Up @@ -325,8 +332,15 @@ def calculate_grade
def change_status
authorize! :change_status, Exam, { on: params[:allocation_tags_ids] }
exam = Exam.find(params[:id])

exam.can_change_status?
exam.update_attributes status: !exam.status

updated_status = !exam.status

log(exam, "exam: #{exam.id} [#{updated_status ? 'publish' : 'unpublish' }], #{exam.attributes.except('id')}", LogAction::TYPE[:update]) rescue nil

exam.update_attributes status: updated_status

render_exam_success_json('status')
rescue CanCan::AccessDenied
render json: { success: false, alert: t(:no_permission) }, status: :unauthorized
Expand Down Expand Up @@ -452,4 +466,12 @@ def return_acu_result(acu, at_id, score_type)
render json: { success: false, alert: error }
end

def log(object, message, type=LogAction::TYPE[:update])
user_params = { user_id: current_user.id, ip: get_remote_ip }

object.academic_allocations.each do |ac|
LogAction.create(user_params.merge!(description: "user_id: #{user_params[:user_id]}, #{message}", academic_allocation_id: ac.id, log_type: type))
end
end

end
2 changes: 1 addition & 1 deletion app/controllers/questions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def update
end

if @question.update_attributes question_params
render partial: 'question', locals: { question: @question }
render partial: 'question', locals: { question: @question, can_show_order: true }
else
@errors = []
@question.errors.each do |attribute, erro|
Expand Down
205 changes: 128 additions & 77 deletions app/models/concerns/sys_log.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,62 +10,49 @@ module Actions
extend ActiveSupport::Concern

included do
after_action :log_create, unless: Proc.new {|c| request.get? }, except: [:change_participant, :import, :export, :annul, :remove_record]
after_action :log_create, unless: Proc.new {|c| request.get? }, except: [:change_participant, :import, :export, :annul, :publish, :remove_record]
end

def log_create
model = self.class.to_s.sub("Controller", "")
sobj = model.tableize
objs = eval("@#{sobj}") # created/updated/destroyied objects could be a list
sobj = sobj.singularize
obj = eval("@#{sobj}")
objs = [eval("@#{sobj}")].compact unless obj.nil? # only if obj doesn't exist, use objs list
ignored_attrs = %w[id created_at updated_at attachment_updated_at]
model_name = self.class.to_s.sub("Controller", "")
sobj = model_name.tableize.singularize

# if some error happened, don't save log
obj = instance_variable_get("@#{sobj}")
objs = instance_variable_get("@#{model_name.tableize}")

response_status = JSON.parse(response.body) rescue nil
Rails.logger.info("\n\n Log Info Obj \n\n #{model_name} \n #{sobj} \n #{obj} \n #{objs} \n\n")

Rails.logger.info("\n\n\n #{model} \n #{sobj} \n #{objs} \n #{obj}")

return if ((!(response_status.nil?) && response_status.has_key?("success") && response_status["success"] == false) || (params.include?(:success) && params[:success] == false))

if !(objs.nil?) && !(objs.empty?)
objs.each do |obj|

# general rule for creating a log description
all_associations = eval("#{model.singularize}").reflect_on_all_associations(:has_many).map(&:name)

log_payload = if obj.respond_to?(:log_description)
obj.log_description
target_objects = if obj.present?
[obj]
elsif objs.present? && objs.is_a?(Enumerable)
objs
else
obj.attributes.except(*ignored_attrs)
[]
end

all_associations.each do |association|
if(obj.respond_to?(association) && obj.send(association).any?)
association_data = obj.send(association).map {|a| a.attributes.except("attachment_updated_at") }

log_payload = log_payload.merge("#{association.to_s}" => association_data) if log_payload.is_a?(Hash)
end
end

description = "#{sobj.singularize}: #{obj.id}#{changed_attributes(obj, ignored_attrs)}, #{log_payload.to_json}"

if ((obj.respond_to?(:academic_allocations) && !obj.try(:academic_allocations).empty?) || obj.respond_to?(:academic_allocation))
allocation_tag_id = params[:allocation_tag_id] || active_tab[:url][:allocation_tag_id] || obj.allocation_tag.id rescue nil

[(obj.respond_to?(:academic_allocations) ? obj.academic_allocations : obj.academic_allocation)].flatten.each do |al|
LogAction.create(log_type: LogAction::TYPE[request_method(request.request_method)], user_id: current_user.id, academic_allocation_id: al.id, allocation_tag_id: (allocation_tag_id || al.allocation_tag_id), ip: get_remote_ip, description: description)
end
elsif (obj.respond_to?(:allocation_tag) && !(obj.allocation_tag.nil?))
LogAction.create(log_type: LogAction::TYPE[request_method(request.request_method)], user_id: current_user.id, allocation_tag_id: obj.allocation_tag.id, ip: get_remote_ip, description: description)
else # generic log
generic_log(sobj, obj)
return if request_failed?

if target_objects.any?
target_objects.each do |obj|
next if obj.new_record? && params.include?(:digital_classes)
description = general_log_description(obj, sobj)
resolved_log_targets = log_targets(obj)

resolved_log_targets.each do |target|
LogAction.create(
log_type: LogAction::TYPE[request_method(request.request_method)],
user_id: current_user.id,
ip: get_remote_ip,
description: description,
academic_allocation_id: target[:allocation_id],
allocation_tag_id: target[:tag_id],
)
end
end
else
generic_log(sobj)
# generic log(fallback)
Rails.logger.info("\n\n Entrou no fallback \n\n")
fallback_log
end

rescue => error
Expand All @@ -81,6 +68,103 @@ def self.log_info(msg = nil, &block)

private

def request_failed?
response_status = JSON.parse(response.body) rescue nil

return true if response_status&.key?("success") && response_status["success"] == false
return true if (params.include?(:success) && params[:success] == false)
false
end

def general_log_description(obj, sobj)
ignored_attrs = %w[id created_at updated_at attachment_updated_at]

log_payload = obj.respond_to?(:log_description) ? obj.log_description : obj.attributes.except(*ignored_attrs)

log_payload = log_payload.as_json unless log_payload.is_a?(Hash)

all_associations = obj.class.reflect_on_all_associations(:has_many).map(&:name)

all_associations.each do |association|
if((obj.respond_to?(association) && obj.send(association).any?) && !(obj.respond_to?(:log_description)))

association_data = obj.send(association).map {|a| a.attributes.except("attachment_updated_at") }

log_payload[association.to_s] = association_data
end
end

"#{sobj.singularize}: #{obj.id}#{changed_attributes(obj, ignored_attrs)}, #{log_payload.to_json}"
end

def log_targets(obj) # academic_allocations and allocation_tag to get allocation_tag_id
targets = []
allocation_tag_id = params[:allocation_tag_id] || active_tab[:url][:allocation_tag_id] || (obj.allocation_tag.id rescue nil)

if obj.respond_to?(:academic_allocations) && obj.academic_allocations.present?
obj.academic_allocations.each do |al|
targets << {
allocation_id: al.id,
tag_id: (allocation_tag_id || al.try(:allocation_tag_id))
}
end
elsif obj.respond_to?(:academic_allocation) && obj.academic_allocation.present?
al = obj.academic_allocation
targets << {
allocation_id: al.id,
tag_id: (allocation_tag_id || al.try(:allocation_tag_id))
}
elsif obj.respond_to?(:allocation_tag) && obj.allocation_tag.present?
targets << { allocation_id: nil, tag_id: obj.allocation_tag.id }
else
targets << { allocation_id: nil, tag_id: allocation_tag_id }
end

targets
end

def fallback_log
return if params.include?(:digital_classes)

description = nil

if params[:id].present? && params.except(:controller, :action, :id).empty?
description = "#{params[:controller].singularize}: #{params[:id]}"
elsif params[:id].present?
info = params.except(:controller, :action, :id).to_json
description = "#{params[:controller].singularize}: #{params[:id]}, #{info}"
else
d = []
variables = self.instance_variable_names.map(&:to_s).reject do |v|
v.start_with?("@_") || ["@current_user", "@current_ability"].include?(v)
end

academic_allocation_id = nil

variables.each do |v|
o = instance_variable_get(v)
next if ["Array", "String", "NilClass"].include?(o.class.to_s)

if o.respond_to?(:academic_allocation) && o.academic_allocation.respond_to?(:id)
academic_allocation_id = o.academic_allocation.id
end

d << %{#{v.sub("@", "")}: #{o.as_json}}
end

description = d.any? ? d.join(', ') : "#{params[:controller]}: #{params.except('controller').to_json}"
end

LogAction.create(
log_type: LogAction::TYPE[request_method(request.request_method)],
user_id: current_user.id,
ip: get_remote_ip,
description: description,
academic_allocation_id: academic_allocation_id,
allocation_tag_id: (active_tab[:url][:allocation_tag_id] rescue nil),
)
end

def changed_attributes(obj, ignored)
return '' unless obj.saved_changes?

Expand All @@ -102,39 +186,6 @@ def request_method(rm)
end
end

def generic_log(sobj, obj = nil)
return if params.include?(:digital_classes)
return if !obj.nil? && obj.new_record?# && !params.include?(:digital_classes) # not saved

# academic_allocation_id = obj.try(:academic_allocation).try(:id)
academic_allocation_id = nil
tbname = obj.try(:class).try(:table_name).to_s.singularize.to_sym if obj.try(:class).respond_to?(:table_name)
description = if !tbname.nil? && (params.has_key?(tbname) || params.size <= 3) && !obj.nil?

obj_attrs = (obj.respond_to?(:log_description) ? obj.log_description : obj.attributes.except('attachment_updated_at', 'created_at', 'updated_at'))
obj_attrs.merge!({'files' => obj.files.map {|f| f.attributes.except('attachment_updated_at') } }) if obj.respond_to?(:files) && obj.files.any?
obj_attrs = ActiveSupport::JSON.encode(obj_attrs)

"#{sobj}: #{obj.id}, changed: #{obj.changed}, #{obj_attrs}"
elsif params[:id].present?
# gets any extra information if exists
info = ActiveSupport::JSON.encode(params.except(:controller, :action, :id))
"#{sobj}: #{[params[:id], info].compact.join(", ")}"
else # controllers saving other objects. ex: assingments -> student files
d = []
variables = self.instance_variable_names.to_ary.delete_if { |v| v.to_s.start_with?("@_") || ["@current_user", "@current_ability"].include?(v) }
variables.each do |v|
o = eval(v)
academic_allocation_id = o.academic_allocation.id if o.respond_to?(:academic_allocation) # assignment_file
d << %{#{v.sub("@", "")}: #{o.as_json}} unless ["Array", "String"].include?(o.class)
end
d.join(', ')
d = "#{params[:controller]}: #{params.except('controller').to_s}" if d.blank?
end

LogAction.create(log_type: LogAction::TYPE[request_method(request.request_method)], user_id: current_user.id, ip: get_remote_ip, academic_allocation_id: academic_allocation_id, description: description, allocation_tag_id: (active_tab[:url][:allocation_tag_id] rescue nil)) unless description.nil?
end

end # Actions

module Devise
Expand Down
16 changes: 10 additions & 6 deletions app/models/exam.rb
Original file line number Diff line number Diff line change
Expand Up @@ -417,13 +417,17 @@ def responses_question_user(acu_id, id)

def log_description
desc = {}

desc.merge!(question.attributes.except('attachment_updated_at', 'updated_at', 'created_at'))
desc.merge!(exam_id: exam.id)
desc.merge!(exam_id: id)
desc.merge!(attributes.except('attachment_updated_at', 'updated_at', 'created_at'))
desc.merge!(images: question.question_images.collect{|img| img.attributes.except('image_updated_at' 'question_id')})
desc.merge!(items: question.question_items.collect{|item| item.attributes.except('question_id', 'item_image_updated_at')})
desc.merge!(labels: question.question_labels.collect{|label| label.attributes.except('created_at', 'updated_at')})
desc.merge!(schedules: schedule.attributes.except('id', 'updated_at', 'created_at'))

questions.each do |question|
desc.merge!(questions: question.attributes.except('attachment_updated_at', 'updated_at', 'created_at'))
desc.merge!(items: question.question_items.collect{|item| item.attributes.except('question_id', 'item_image_updated_at')})
desc.merge!(images: question.question_images.collect{|img| img.attributes.except('image_updated_at' 'question_id')})
desc.merge!(labels: question.question_labels.collect{|label| label.attributes.except('created_at', 'updated_at')})
end
return desc
end

def set_random_questions
Expand Down