diff --git a/app/controllers/admin/dashboards_controller.rb b/app/controllers/admin/dashboards_controller.rb index 27cc1fc..6cd87cf 100644 --- a/app/controllers/admin/dashboards_controller.rb +++ b/app/controllers/admin/dashboards_controller.rb @@ -1,4 +1,9 @@ class Admin::DashboardsController < ApplicationController + before_action :authorize! def show end + + def authorize! + super with: Admin::DashboardPolicy + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 154e651..d3f3f97 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,6 +2,8 @@ class ApplicationController < ActionController::Base before_action :set_current_request_details before_action :authenticate_user! + verify_authorized + private def current_user Current.user || authenticate_user_from_session diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controller.rb index a4734bf..eefaff2 100644 --- a/app/controllers/jobs_controller.rb +++ b/app/controllers/jobs_controller.rb @@ -1,8 +1,11 @@ class JobsController < ApplicationController - skip_before_action :authenticate_user!, only: :index + skip_before_action :authenticate_user!, only: [ :index, :cancel_button ] + skip_verify_authorized only: [ :index, :new, :create, :cancel_button ] + # GET /jobs or /jobs.json def index @jobs = Job.currently_working_on + @no_turbo_stream = true end # GET /jobs/new @@ -28,6 +31,7 @@ class JobsController < ApplicationController def cancel @job = Job.find(params[:id]) + authorize! @job if @job.canceled! flash[:notice] = "Job successfully canceled" @status_changed = true @@ -42,6 +46,12 @@ class JobsController < ApplicationController end end + def cancel_button + @job = Job.find(params[:id]) + + render partial: "jobs/cancel_button", locals: { job: @job } + end + private def broadcast_update_status_cards_and_start_next_job_button diff --git a/app/controllers/operator/jobs_controller.rb b/app/controllers/operator/jobs_controller.rb index 7574fd9..0614281 100644 --- a/app/controllers/operator/jobs_controller.rb +++ b/app/controllers/operator/jobs_controller.rb @@ -1,6 +1,7 @@ class Operator::JobsController < ApplicationController before_action :set_job, only: %i[show edit update destroy increment_page decrement_page] before_action :set_job_lists, only: %i[index] + before_action :authorize! # GET /jobs or /jobs.json def index @@ -133,7 +134,7 @@ class Operator::JobsController < ApplicationController end def broadcast_update_job - Turbo::StreamsChannel.broadcast_replace_later_to "jobs", target: @job, partial: "jobs/job_tr", locals: { job: @job } + Turbo::StreamsChannel.broadcast_replace_later_to "jobs", target: @job, partial: "jobs/job_tr", locals: { job: @job } if @status_changed Turbo::StreamsChannel.broadcast_remove_to "operator_jobs", target: @job broadcast_update_status_cards_and_start_next_job_button diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 1956a8b..d9caf5f 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -1,4 +1,5 @@ class PasswordsController < ApplicationController + skip_verify_authorized only: [ :edit, :update ] before_action :set_user def edit diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 3889d62..6bca1f0 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -1,4 +1,6 @@ class ProfilesController < ApplicationController + skip_verify_authorized only: [ :show, :edit, :destroy ] + def show end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5a686b2..0ca4fae 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,5 +1,6 @@ class SessionsController < ApplicationController skip_before_action :authenticate_user!, only: %i[ new create ] + skip_verify_authorized only: [ :index, :new, :create, :destroy ] before_action :set_session, only: :destroy diff --git a/app/policies/admin/dashboard_policy.rb b/app/policies/admin/dashboard_policy.rb new file mode 100644 index 0000000..ea4ca08 --- /dev/null +++ b/app/policies/admin/dashboard_policy.rb @@ -0,0 +1,4 @@ +class Admin::DashboardPolicy < ApplicationPolicy + def show + end +end diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index a68373b..8317d54 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -1,5 +1,12 @@ # Base class for application policies class ApplicationPolicy < ActionPolicy::Base + pre_check :allow_admins + + # admin is good! :) + def allow_admins + allow! if user.admin? + end + # Configure additional authorization contexts here # (`user` is added by default). # @@ -7,6 +14,7 @@ class ApplicationPolicy < ActionPolicy::Base # # Read more about authorization context: https://actionpolicy.evilmartians.io/#/authorization_context + private # Define shared methods useful for most policies. diff --git a/app/policies/job_policy.rb b/app/policies/job_policy.rb index 5e17197..ed476e1 100644 --- a/app/policies/job_policy.rb +++ b/app/policies/job_policy.rb @@ -1,9 +1,12 @@ class JobPolicy < ApplicationPolicy + skip_pre_check :allow_admins, only: :cancel? + + def cancel? + record.open? && (user == record.costumer || user.operator? || user.admin?) + end + # See https://actionpolicy.evilmartians.io/#/writing_policies # - # def index? - # true - # end # # def update? # # here we can access our context and record diff --git a/app/policies/operator/job_policy.rb b/app/policies/operator/job_policy.rb new file mode 100644 index 0000000..ca2e4d1 --- /dev/null +++ b/app/policies/operator/job_policy.rb @@ -0,0 +1,21 @@ +class Operator::JobPolicy < ApplicationPolicy + pre_check :allow_operators + + def index? + end + + def update? + end + + def increment_page? + end + + def decrement_page? + end + + private + + def allow_operators + allow! if user.operator? + end +end diff --git a/app/policies/session_policy.rb b/app/policies/session_policy.rb new file mode 100644 index 0000000..b33d93f --- /dev/null +++ b/app/policies/session_policy.rb @@ -0,0 +1,5 @@ +class SessionPolicy < ApplicationPolicy + def new? + true + end +end diff --git a/app/views/jobs/_cancel_button.html.erb b/app/views/jobs/_cancel_button.html.erb new file mode 100644 index 0000000..a30b8c5 --- /dev/null +++ b/app/views/jobs/_cancel_button.html.erb @@ -0,0 +1,28 @@ +<%= turbo_frame_tag dom_id(job, :cancel_button) do %> + <%# TODO: Refactor! %> + <% if current_user %> + <% if allowed_to? :cancel?, job %> + <%= button_to icon("x-circle", class: "icon size-10 text-hsrm-red", title: "Druckauftrag abbrechen (Anmeldung erforderlich)"), cancel_job_path(job), method: :patch, form: {data: {turbo_confirm: 'Den Plottauftrag wirklich abbrechen?'}}, form_class: "inline" %> + <% else %> + <% if job.open? %> + <% if job.created_by_operator %> + <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Druckauftrag kann nur vom Operator abgebrochen werden!") %> + <% else %> + <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Sie sind nicht berechtigt diesen Druckauftrag abzubrechen") %> + <% end %> + <% else %> + <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Kann nicht mehr abgebrochen werden") %> + <% end %> + <% end %> + <% else %> + <% if job.open? %> + <% if job.created_by_operator %> + <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Druckauftrag kann nur vom Operator abgebrochen werden!") %> + <% else %> + <%= button_to icon("x-circle", class: "icon size-10 text-hsrm-red", title: "Druckauftrag abbrechen (Anmeldung erforderlich)"), cancel_job_path(job), method: :patch, form: {data: {turbo_confirm: 'Den Plottauftrag wirklich abbrechen? (Anmeldung erforderlich!)'}}, form_class: "inline" %> + <% end %> + <% else %> + <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Kann nicht mehr abgebrochen werden") %> + <% end %> + <% end %> +<% end %> diff --git a/app/views/jobs/_job_tr.html.erb b/app/views/jobs/_job_tr.html.erb index 452993e..b7cb493 100644 --- a/app/views/jobs/_job_tr.html.erb +++ b/app/views/jobs/_job_tr.html.erb @@ -54,10 +54,15 @@ - <% if job.open? %> - <%= button_to icon("x-circle", class: "icon size-10 text-hsrm-red", title: "Abbrechen"), cancel_job_path(job), method: :patch, form: {data: {turbo_confirm: 'Den Plottauftrag wirklich abbrechen?'}}, form_class: "inline" %> + <% # TODO: Refactor to helper function %> + <% if defined?(no_turbo_stream) && no_turbo_stream %> + <%= turbo_frame_tag dom_id(job, :cancel_button) do %> + <%= render partial: "jobs/cancel_button", locals: { job: job } %> + <% end %> <% else %> - <%= icon("x-circle", class: "icon icon-disabled size-10", title: "Kann nicht mehr abgebrochen werden") %> + <%= turbo_frame_tag dom_id(job, :cancel_button), src: cancel_button_job_path(job), loading: 'lazy' do %> + <%= icon("ellipsis-horizontal-circle", class: "icon icon-disabled size-10", title: "Loading...") %> + <% end %> <% end %> diff --git a/app/views/jobs/index.html.erb b/app/views/jobs/index.html.erb index 2f631cc..d872b35 100644 --- a/app/views/jobs/index.html.erb +++ b/app/views/jobs/index.html.erb @@ -1,6 +1,5 @@ <%= turbo_stream_from 'jobs' %>
- <%#= render partial: 'layouts/flash' %> <% content_for :title, "Current Print Jobs" %>

Aktuelle Druckaufträge <%= Date.today.strftime("%d.%m.%Y") %>

@@ -25,8 +24,7 @@ - <%= render partial: "job_tr", collection: @jobs, as: :job %> - <%#= link_to "Show this job", job, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %> + <%= render partial: "job_tr", collection: @jobs, as: :job, locals: { no_turbo_stream: @no_turbo_stream } %>
diff --git a/config/routes.rb b/config/routes.rb index 13e9b12..3f29325 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,7 @@ Rails.application.routes.draw do resources :jobs, only: [ :index, :new, :create ] do member do patch "cancel" + get "cancel_button" end end resource :profile, only: [ :show, :edit, :destroy ] diff --git a/test/policies/admin/dashboard_policy_test.rb b/test/policies/admin/dashboard_policy_test.rb new file mode 100644 index 0000000..cdd3afd --- /dev/null +++ b/test/policies/admin/dashboard_policy_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +# See https://actionpolicy.evilmartians.io/#/testing?id=testing-policies +class Admin::DashboardPolicyTest < ActiveSupport::TestCase + def test_index + end + + def test_create + end + + def test_manage + end +end diff --git a/test/policies/operator/job_policy_test.rb b/test/policies/operator/job_policy_test.rb new file mode 100644 index 0000000..82d8998 --- /dev/null +++ b/test/policies/operator/job_policy_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +# See https://actionpolicy.evilmartians.io/#/testing?id=testing-policies +class Operator::JobPolicyTest < ActiveSupport::TestCase + def test_index + end + + def test_create + end + + def test_manage + end +end diff --git a/test/policies/session_policy_test.rb b/test/policies/session_policy_test.rb new file mode 100644 index 0000000..7518c0d --- /dev/null +++ b/test/policies/session_policy_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +# See https://actionpolicy.evilmartians.io/#/testing?id=testing-policies +class SessionPolicyTest < ActiveSupport::TestCase + def test_index + end + + def test_create + end + + def test_manage + end +end