-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restrict surveys access if code required (#12)
* restrict surveys unless code * add tests * fix tests * add overrides spec * add intermediate table for resouce links and usage_count * fix tests * ensure no duplicated tokens on the same group * fix seeds * rename examples
- Loading branch information
1 parent
4dd10fc
commit e60439c
Showing
21 changed files
with
611 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
app/controllers/concerns/decidim/anonymous_codes/surveys_controller_override.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module AnonymousCodes | ||
module SurveysControllerOverride | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
before_action do | ||
next unless current_settings.allow_answers? && survey.open? | ||
next if visitor_already_answered? | ||
|
||
if token_groups.any? | ||
next if current_token&.available? | ||
|
||
if current_token.blank? | ||
flash.now[:alert] = I18n.t("decidim.anonymous_codes.invalid_code") if params.has_key?(:token) | ||
elsif current_token.used? | ||
flash.now[:alert] = I18n.t("decidim.anonymous_codes.used_code") | ||
elsif current_token.expired? | ||
flash.now[:alert] = I18n.t("decidim.anonymous_codes.expired_code") | ||
end | ||
render "decidim/anonymous_codes/surveys/code_required" | ||
end | ||
end | ||
|
||
after_action only: :answer do | ||
next unless current_token&.available? | ||
|
||
# find any answer for the current user and questionnaire that would be used as a resource to link the usage counter | ||
answer = Decidim::Forms::Answer.find_by(questionnaire: questionnaire, user: current_user, session_token: @form.context.session_token) | ||
current_token.answers << answer if answer.present? | ||
end | ||
|
||
private | ||
|
||
def token_groups | ||
@token_groups ||= Decidim::AnonymousCodes::Group.where(resource: survey, active: true) | ||
end | ||
|
||
def current_token | ||
@current_token ||= Decidim::AnonymousCodes::Token.where(group: token_groups).find_by(token: token_param) | ||
end | ||
|
||
def token_param | ||
@token_param ||= begin | ||
session[:anonymous_codes_token] = params[:token] if params.has_key?(:token) | ||
session[:anonymous_codes_token] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module AnonymousCodes | ||
class TokenResource < ApplicationRecord | ||
self.table_name = :decidim_anonymous_codes_token_resources | ||
|
||
belongs_to :token, class_name: "Decidim::AnonymousCodes::Token", counter_cache: :usage_count | ||
belongs_to :resource, polymorphic: true | ||
|
||
validate :max_uses_not_exceeded | ||
validate :valid_parent_questionnaire | ||
|
||
private | ||
|
||
def max_uses_not_exceeded | ||
return unless token.usage_count >= token.group.max_reuses | ||
|
||
errors.add(:base, :max_uses_exceeded) | ||
end | ||
|
||
def valid_parent_questionnaire | ||
return unless resource.try(:questionnaire) != token.group.resource.try(:questionnaire) | ||
|
||
errors.add(:base, :invalid_questionnaire) | ||
end | ||
end | ||
end | ||
end |
50 changes: 50 additions & 0 deletions
50
app/views/decidim/anonymous_codes/surveys/code_required.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<% add_decidim_meta_tags({ | ||
title: translated_attribute(questionnaire.title), | ||
description: translated_attribute(questionnaire.description), | ||
}) %> | ||
|
||
<%= render partial: "decidim/shared/component_announcement" if current_component.manifest_name == "surveys" %> | ||
|
||
<div class="row columns"> | ||
<h2 class="section-heading"><%= translated_attribute questionnaire.title %></h2> | ||
<div class="row"> | ||
<div class="columns large-6 medium-centered lead"> | ||
<%= decidim_sanitize_editor_admin translated_attribute questionnaire.description %> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="row"> | ||
<div class="columns large-6 medium-centered"> | ||
<div class="card"> | ||
<div class="card__content"> | ||
<% unless questionnaire_for.try(:component)&.try(:published?) %> | ||
<div class="section"> | ||
<div class="callout warning"> | ||
<p><%= t("questionnaire_not_published.body", scope: "decidim.forms.questionnaires.show") %></p> | ||
</div> | ||
</div> | ||
<% end %> | ||
|
||
<div class="section"> | ||
<div class="callout warning"> | ||
<h3 class="heading4"><%= t(".title") %></h3> | ||
<p><%= t(".body") %></p> | ||
</div> | ||
<fi3eldset class="field"> | ||
<label class="field__label" for="code"><%= t(".label") %></label> | ||
<div class="field__input"> | ||
<form method="get"> | ||
<%= text_field_tag :token, nil, class: "input", required: true %> | ||
<button type="submit" class="button"><%= t(".submit") %></button> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<% content_for :js_content do %> | ||
<%= javascript_pack_tag "decidim_forms" %> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
db/migrate/20240403091376_create_decidim_anonymous_codes_token_resources.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
|
||
class CreateDecidimAnonymousCodesTokenResources < ActiveRecord::Migration[6.1] | ||
def change | ||
create_table :decidim_anonymous_codes_token_resources do |t| | ||
t.references :token, null: false, index: { name: "decidim_anonymous_codes_token_resources_on_token" } | ||
t.references :resource, polymorphic: true, null: false, index: { name: "decidim_anonymous_codes_token_resources_on_resource" } | ||
t.timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,54 @@ | ||
# frozen_string_literal: true | ||
|
||
if !Rails.env.production? || ENV.fetch("SEED", nil) | ||
print "Creating seeds for decidim_anonymous_codes...\n" unless Rails.env.test? | ||
|
||
organization = Decidim::Organization.first | ||
participatory_processes = Decidim::ParticipatoryProcess.where(organization: organization) | ||
|
||
unless participatory_processes.count.positive? | ||
puts "No participatory processes found. Skipping seeds for decidim_anonymous_codes..." | ||
return | ||
end | ||
print "Creating seeds for decidim_anonymous_codes...\n" unless Rails.env.test? | ||
|
||
group1 = Decidim::AnonymousCodes::Group.create!( | ||
title: { en: "First Group" }, | ||
organization: organization, | ||
expires_at: 1.week.from_now, | ||
active: true, | ||
max_reuses: 1, | ||
resource: Decidim::Surveys::Survey.first | ||
) | ||
admin = Decidim::User.where(admin: true).first | ||
survey_components = Decidim::Component.where(manifest_name: "surveys", participatory_space: participatory_processes) | ||
survey_components.each do |component| | ||
form = OpenStruct.new(name: component.name, weight: component.weight, settings: component.settings, default_step_settings: component.default_step_settings, | ||
step_settings: component.step_settings) | ||
form.step_settings.each do |key, _value| | ||
form.step_settings[key]["allow_answers"] = true | ||
form.step_settings[key]["allow_unregistered"] = true | ||
end | ||
Decidim::Admin::UpdateComponent.call(form, component, admin) do | ||
on(:ok) do | ||
puts "Component #{component.id} updated for allowing answers and unregistered users" | ||
end | ||
|
||
group2 = Decidim::AnonymousCodes::Group.create!( | ||
title: { en: "Second Group" }, | ||
organization: organization, | ||
expires_at: 1.week.from_now, | ||
active: true, | ||
max_reuses: 1, | ||
resource: Decidim::Surveys::Survey.second | ||
) | ||
on(:invalid) do | ||
puts "ERROR: Component #{component.id} not updated for allowing answers and unregistered users" | ||
end | ||
end | ||
|
||
5.times do | ||
Decidim::AnonymousCodes::Token.create!(token: Decidim::AnonymousCodes.token_generator, usage_count: 0, group: group1) | ||
end | ||
survey = Decidim::Surveys::Survey.find_by(component: component) | ||
next unless survey | ||
|
||
25.times do | ||
Decidim::AnonymousCodes::Token.create!(token: Decidim::AnonymousCodes.token_generator, usage_count: 0, group: group2) | ||
group = Decidim.traceability.create!( | ||
Decidim::AnonymousCodes::Group, | ||
admin, | ||
{ | ||
title: { en: "Group for Survey #{survey.id}" }, | ||
organization: organization, | ||
expires_at: 1.week.from_now, | ||
active: rand(2).zero?, | ||
max_reuses: rand(3), | ||
resource: survey | ||
}, | ||
visibility: "admin-only" | ||
) | ||
total = rand(1..25) | ||
total.times do | ||
Decidim::AnonymousCodes::Token.create!(token: Decidim::AnonymousCodes.token_generator, group: group) | ||
end | ||
puts "Created #{total} tokens for survey #{survey.id}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.