Skip to content

Commit

Permalink
Center authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
fblupi committed Dec 4, 2023
1 parent 662ce09 commit ce70e15
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 2 deletions.
25 changes: 25 additions & 0 deletions app/forms/decidim/centers/verifications/center.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require "digest"

module Decidim
module Centers
module Verifications
class Center < Decidim::AuthorizationHandler
validate :center_present

def metadata
super.merge(
centers: user.centers.pluck(:id)
)
end

protected

def center_present
errors.add(:user, I18n.t("decidim.centers.authorizations.new.error")) unless user.centers.any?
end
end
end
end
end
46 changes: 46 additions & 0 deletions app/jobs/decidim/centers/auto_verification_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

module Decidim
module Centers
class AutoVerificationJob < ApplicationJob
queue_as :default

def perform(user_id)
@user = Decidim::User.find(user_id)
@user.centers.any? ? create_auth : remove_auth
rescue ActiveRecord::RecordNotFound => _e
Rails.logger.error "AutoVerificationJob: ERROR: user not found #{user_id}"
end

private

def create_auth
return unless (handler = Decidim::AuthorizationHandler.handler_for("center", user: @user))

Decidim::Verifications::AuthorizeUser.call(handler, @user.organization) do
on(:ok) do
Rails.logger.info "AutoVerificationJob: Success: created for user #{handler.user.id}"
end

on(:invalid) do
Rails.logger.error "AutoVerificationJob: ERROR: not created for user #{handler.user&.id}"
end
end
end

def remove_auth
Decidim::Authorization.where(user: @user, name: "center").each do |auth|
Decidim::Verifications::DestroyUserAuthorization.call(auth) do
on(:ok) do
Rails.logger.info "AutoVerificationJob: Success: removed for user #{auth.user.id}"
end

on(:invalid) do
Rails.logger.error "AutoVerificationJob: ERROR: not removed for user #{auth.user&.id}"
end
end
end
end
end
end
end
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ en:
create: "%{user_name} created the %{resource_name} center"
delete: "%{user_name} deleted the %{resource_name} center"
update: "%{user_name} updated the %{resource_name} center"
authorizations:
new:
error: The user has no center configured
models:
center:
fields:
Expand Down
7 changes: 7 additions & 0 deletions lib/decidim/centers/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ class Engine < ::Rails::Engine
initializer "decidim_centers.sync" do
ActiveSupport::Notifications.subscribe "decidim.centers.user.updated" do |_name, data|
Decidim::Centers::SyncCenterUserJob.perform_now(data)
Decidim::Centers::AutoVerificationJob.perform_later(data[:user_id])
end
end

initializer "decidim_centers.authorizations" do
Decidim::Verifications.register_workflow(:center) do |workflow|
workflow.form = "Decidim::Centers::Verifications::Center"
end
end

Expand Down
13 changes: 13 additions & 0 deletions lib/decidim/centers/test/shared_contexts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

def check_center_authorization(authorization, user, center)
expect(authorization.name).to eq("center")
expect(authorization.user).to eq(user)
expect(authorization.metadata["centers"]).to include(center.id)
end

shared_examples_for "no authorization is created" do
it "does not create an authorization" do
expect { subject.perform_now(params) }.not_to change(Decidim::Authorization, :count)
end
end
40 changes: 40 additions & 0 deletions spec/forms/decidim/centers/verifications/center_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
module Centers
module Verifications
describe Center do
subject { described_class.from_params(attributes) }

let(:attributes) do
{
"user" => user
}
end
let(:user) { center_user.user }
let(:center_user) { create :center_user }
let(:metadata) do
{
centers: [center_user.center.id]
}
end

context "when everything is ok" do
it { is_expected.to be_valid }

it "returns valid metadata" do
expect(subject.metadata).to eq(metadata)
end
end

context "when the user has no center" do
let(:user) { create :user }

it { is_expected.not_to be_valid }
end
end
end
end
end
91 changes: 91 additions & 0 deletions spec/jobs/centers/auto_verification_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# frozen_string_literal: true

require "spec_helper"
require "decidim/centers/test/shared_contexts"

module Decidim
module Centers
describe AutoVerificationJob do
subject { described_class }

describe "queue" do
it "is queued to events" do
expect(subject.queue_name).to eq "default"
end
end

describe "perform" do
let(:user) { create :user }
let(:params) { user.id }

before do
allow(Rails.logger).to receive(:info).and_call_original
allow(Rails.logger).to receive(:error).and_call_original
end

context "when the user has no center" do
it_behaves_like "no authorization is created"

context "when there is a previous authorization for the user" do
let!(:authorization) { create :authorization, name: "center", user: user }

it "removes an authorization" do
expect { subject.perform_now(params) }.to change(Decidim::Authorization, :count).by(-1)
end

context "when the authorization cannot be removed" do
before do
# rubocop: disable RSpec/AnyInstance
allow_any_instance_of(Decidim::Verifications::DestroyUserAuthorization).to receive(:authorization).and_return(nil)
# rubocop: enable RSpec/AnyInstance
end

it "writes an error log" do
subject.perform_now(params)
expect(Rails.logger).to have_received(:error).with(/AutoVerificationJob: ERROR: not removed for user/)
end
end
end
end

context "when the user has center" do
let!(:center_user) { create :center_user, user: user }

it "creates an authorization" do
expect { subject.perform_now(params) }.to change(Decidim::Authorization, :count).by(1)
end

context "when the authorization cannot be created" do
before do
# rubocop: disable RSpec/AnyInstance
allow_any_instance_of(Decidim::AuthorizationHandler).to receive(:invalid?).and_return(true)
# rubocop: enable RSpec/AnyInstance
end

it "writes an error log" do
subject.perform_now(params)
expect(Rails.logger).to have_received(:error).with(/AutoVerificationJob: ERROR: not created for user/)
end
end

context "when there is a previous authorization for the user" do
let!(:authorization) { create :authorization, name: "center", user: user }

it_behaves_like "no authorization is created"
end
end

context "when the user does not exist" do
let(:params) { -1 }

it_behaves_like "no authorization is created"

it "writes an error log" do
subject.perform_now(params)
expect(Rails.logger).to have_received(:error).with(/AutoVerificationJob: ERROR: user not found/)
end
end
end
end
end
end
47 changes: 47 additions & 0 deletions spec/jobs/centers/sync_center_user_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
module Centers
describe SyncCenterUserJob do
subject { described_class }

describe "queue" do
it "is queued to events" do
expect(subject.queue_name).to eq "default"
end
end

describe "perform" do
let(:user) { create :user }
let(:center) { create :center }
let(:params) { { user_id: user.id, center_id: center.id } }

before do
allow(Rails.logger).to receive(:info).and_call_original
allow(Rails.logger).to receive(:error).and_call_original
subject.perform_now(params)
end

context "when the sync runs successfully" do
it "writes an info log" do
expect(Rails.logger).to have_received(:info).with(/SyncCenterUserJob: Success/)
end
end

context "when the sync fails" do
before do
# rubocop: disable RSpec/AnyInstance
allow_any_instance_of(Decidim::Centers::CreateOrUpdateCenterUser).to receive(:delete_existing_center_user!).and_raise
# rubocop: enable RSpec/AnyInstance
end

it "writes an error log" do
expect(Rails.logger).to have_received(:error).with(/SyncCenterUserJob: ERROR/)
end
end
end
end
end
end
11 changes: 10 additions & 1 deletion spec/system/account_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "spec_helper"
require "decidim/centers/test/shared_contexts"

describe "Account", type: :system do
let(:organization) { create :organization }
Expand All @@ -14,7 +15,7 @@
end

shared_examples_for "user changes the center" do
it "can update the center" do
it "can update the center and changes the authorization" do
within "form.edit_user" do
within "#user_center_id" do
find("option[value='#{other_center.id}']").click
Expand All @@ -28,6 +29,9 @@
end

expect(find("#user_center_id").value).to eq(other_center.id.to_s)

perform_enqueued_jobs
check_center_authorization(Decidim::Authorization.last, user, other_center)
end
end

Expand All @@ -45,11 +49,16 @@

context "when the user has center" do
let!(:center_user) { create :center_user, center: center, user: user }
let!(:authorization) { create :authorization, name: "center", user: user, metadata: { centers: [center.id] } }

before do
visit decidim.account_path
end

it "has an authorization for the center" do
check_center_authorization(Decidim::Authorization.last, user, center)
end

it "shows the current center on the center input" do
expect(find("#user_center_id").value).to eq(center.id.to_s)
end
Expand Down
6 changes: 5 additions & 1 deletion spec/system/registration_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "spec_helper"
require "decidim/centers/test/shared_contexts"

describe "Registration spec", type: :system do
let(:organization) { create :organization }
Expand Down Expand Up @@ -28,7 +29,7 @@
end
end

it "allows to create a new account" do
it "allows to create a new account and authorizes the user with the center provided" do
fill_in :registration_user_name, with: name
fill_in :registration_user_nickname, with: nickname
fill_in :registration_user_email, with: email
Expand All @@ -48,5 +49,8 @@

expect(page).to have_content("message with a confirmation link has been sent")
expect(Decidim::User.last.center).to eq(center)

perform_enqueued_jobs
check_center_authorization(Decidim::Authorization.last, Decidim::User.last, center)
end
end

0 comments on commit ce70e15

Please sign in to comment.