forked from consuldemocracy/consuldemocracy
-
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.
* #18 Partial implementation for user verification * #18 Add validation for CNP * #18 Add working implementation for validation * #18 Fix unsafe stripping * Add test for CNP validation, split up terms checkboxes Add a very basic system spec for the new CNP verification flow. Split up the checkbox to accept terms, residency, and adult status into three separate checkboxes. Co-authored-by: tsundokul <[email protected]>
- Loading branch information
Showing
12 changed files
with
348 additions
and
23 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Verification::LetterController < ApplicationController | ||
before_action :authenticate_user! | ||
skip_authorization_check | ||
|
||
def new | ||
redirect_to account_path | ||
end | ||
|
||
alias_method :create, :new | ||
alias_method :show, :new | ||
alias_method :edit, :new | ||
alias_method :update, :new | ||
end |
36 changes: 36 additions & 0 deletions
36
app/controllers/custom/verification/residence_controller.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,36 @@ | ||
class Verification::ResidenceController < ApplicationController | ||
before_action :authenticate_user! | ||
before_action :verify_verified! | ||
before_action :verify_lock, only: [:new, :create] | ||
skip_authorization_check | ||
|
||
def new | ||
@residence = Verification::Residence.new | ||
@sms = Verification::Sms.new | ||
end | ||
|
||
def create | ||
@residence = Verification::Residence.new(residence_params.merge(user: current_user)) | ||
@sms = Verification::Sms.new(phone: params[:verification_sms][:phone], user: current_user) | ||
|
||
# Check validity for both objects | ||
# Not using just an if to force both checks | ||
sv = @sms.valid? | ||
rv = @residence.valid? | ||
|
||
if sv && rv | ||
@residence.save | ||
@sms.save | ||
|
||
redirect_to '/account', notice: t("verification.sms.update.flash.level_three.success") | ||
else | ||
render :new | ||
end | ||
end | ||
|
||
private | ||
|
||
def residence_params | ||
params.require(:residence).permit(:document_number, :document_type, :date_of_birth, :postal_code, :terms_of_service, :adult, :resident, sms_attributes: [:phone]) | ||
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 |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# disable SMS validation | ||
class Verification::SmsController < ApplicationController | ||
before_action :authenticate_user! | ||
skip_authorization_check | ||
|
||
def new | ||
redirect_to account_path | ||
end | ||
|
||
alias_method :create, :new | ||
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
require_dependency Rails.root.join('app', 'models', 'setting').to_s | ||
|
||
# [code4ro] | ||
# Enable user verification by default | ||
Setting["feature.user.skip_verification"] = false |
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,26 +1,116 @@ | ||
require_dependency Rails.root.join("app", "models", "verification", "residence").to_s | ||
|
||
class Verification::Residence | ||
validate :local_postal_code | ||
validate :local_residence | ||
include ActiveModel::Model | ||
include ActiveModel::Dates | ||
include ActiveModel::Validations::Callbacks | ||
|
||
attr_accessor :user, :document_number, :document_type, :date_of_birth, :postal_code, :terms_of_service, | ||
:adult, :resident | ||
|
||
before_validation :retrieve_census_data | ||
|
||
validates :document_number, presence: true | ||
validates :terms_of_service, acceptance: { allow_nil: false } | ||
validates :adult, acceptance: { allow_nil: false } | ||
validates :resident, acceptance: { allow_nil: false } | ||
|
||
validate :document_number_uniqueness | ||
validate :document_number_format | ||
|
||
def local_postal_code | ||
errors.add(:postal_code, I18n.t("verification.residence.new.error_not_allowed_postal_code")) unless valid_postal_code? | ||
def initialize(attrs = {}) | ||
attrs = remove_date("date_of_birth", attrs) | ||
super | ||
|
||
clean_document_number | ||
end | ||
|
||
def local_residence | ||
return if errors.any? | ||
def save | ||
self.date_of_birth = date_of_birth_from_document | ||
return false unless valid? | ||
|
||
user.take_votes_if_erased_document(document_number, document_type) | ||
|
||
user.update(document_number: document_number, | ||
document_type: document_type, | ||
date_of_birth: date_of_birth.in_time_zone.to_datetime, | ||
gender: gender, | ||
residence_verified_at: Time.current) | ||
end | ||
|
||
unless residency_valid? | ||
errors.add(:local_residence, false) | ||
store_failed_attempt | ||
Lock.increase_tries(user) | ||
def save! | ||
validate! && save | ||
end | ||
|
||
def allowed_age | ||
return if errors[:date_of_birth].any? | ||
|
||
errors.add(:date_of_birth, I18n.t("verification.residence.new.error_not_allowed_age")) | ||
end | ||
|
||
def document_number_uniqueness | ||
errors.add(:document_number, I18n.t("errors.messages.taken")) if User.active.where(document_number: document_number).any? | ||
end | ||
|
||
def document_number_format | ||
unless looks_like_cnp? document_number | ||
errors.add(:document_number, I18n.t("errors.messages.invalid")) | ||
end | ||
end | ||
|
||
def looks_like_cnp? doc_num | ||
is_number?(doc_num) && doc_num.size == 13 && doc_num[0] != '9' | ||
end | ||
|
||
def store_failed_attempt | ||
FailedCensusCall.create( | ||
user: user, | ||
document_number: document_number, | ||
document_type: document_type, | ||
date_of_birth: date_of_birth_from_document, | ||
postal_code: postal_code | ||
) | ||
end | ||
|
||
def date_of_birth_from_document | ||
return unless looks_like_cnp? document_number | ||
|
||
day = document_number[5..6].to_i | ||
month = document_number[3..4].to_i | ||
year = document_number[1..2].to_i | ||
year += case gender_digit | ||
when 1..2 | ||
1900 | ||
when 3..4 | ||
1800 | ||
when 5..8 | ||
2000 | ||
end | ||
|
||
Date.new(year, month, day) rescue errors.add(:document_number, I18n.t("errors.messages.invalid")) | ||
end | ||
|
||
def gender_digit | ||
document_number.first.to_i | ||
end | ||
|
||
def gender | ||
if [1, 3, 5, 7].include?(gender_digit) | ||
return 'male' | ||
elsif [2, 4, 6, 8].include?(gender_digit) | ||
return 'female' | ||
end | ||
end | ||
|
||
def is_number? string | ||
true if Float(string) rescue false | ||
end | ||
|
||
private | ||
|
||
def valid_postal_code? | ||
postal_code =~ /^280/ | ||
def retrieve_census_data | ||
@census_data = CensusCaller.new.call(document_type, document_number, date_of_birth_from_document, postal_code) | ||
end | ||
|
||
def clean_document_number | ||
self.document_number = document_number&.strip | ||
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 |
---|---|---|
@@ -0,0 +1,28 @@ | ||
class Verification::Sms | ||
include ActiveModel::Model | ||
|
||
attr_accessor :user, :phone, :confirmation_code | ||
|
||
validates :phone, presence: true | ||
validates :phone, format: { with: /\A[\d\+]{10,}\z/ } | ||
validate :uniqness_phone | ||
|
||
def uniqness_phone | ||
errors.add(:phone, :taken) if User.where(confirmed_phone: phone).any? unless phone.blank? | ||
end | ||
|
||
def save | ||
return false unless valid? | ||
|
||
update_user_phone_information | ||
end | ||
|
||
def update_user_phone_information | ||
user.update(unconfirmed_phone: phone, confirmed_phone: phone, sms_confirmation_code: '', verified_at: Time.current) | ||
end | ||
|
||
# Always true since verification is disabled | ||
def verified? | ||
true | ||
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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<% if resource.errors.any? %> | ||
<div id="error_explanation" data-alert class="callout alert" data-closable> | ||
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
|
||
<strong> | ||
<% if local_assigns[:message].present? %> | ||
<%= message %> | ||
<% else %> | ||
<%= sanitize(t("form.not_saved", resource: t("form.#{resource.class.to_s.underscore}"))) %> | ||
<% end %> | ||
</strong> | ||
</div> | ||
<% 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 |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<div class="verification account row"> | ||
<% track_event(category: "verification", action: "start_census") %> | ||
<div class="small-12 column"> | ||
|
||
<%= back_link_to account_path, t("verification.back") %> | ||
|
||
<h1 class="d-block"><%= t("verification.residence.new.title") %></h1> | ||
|
||
<div class="user-permissions small-12"> | ||
|
||
<p><%= t("verification.user_permission_info_budgets") %></p> | ||
<p><%= raw t("verification.residence.new.help_needed", | ||
email: mail_to(Rails.configuration.deploy['support_email']) | ||
) %> | ||
</p> | ||
<hr/> | ||
|
||
</div> | ||
|
||
<%= form_for @residence, as: "residence", url: residence_path do |f| %> | ||
|
||
<%= render "errors" %> | ||
|
||
<div class="row"> | ||
<div class="small-12 medium-4 column"> | ||
|
||
<div class="inline-block"> | ||
<%= f.label t("verification.residence.new.document_number") %> | ||
</div> | ||
|
||
<button type="button" class="inline-block" data-toggle="info-document-number"> | ||
<span class="icon-help"></span> | ||
<span class="show-for-sr"><%= t("verification.residence.new.document_number_help_title") %></span> | ||
</button> | ||
|
||
<div class="dropdown-pane" id="info-document-number" data-dropdown | ||
data-hover="true" data-hover-pane="true"> | ||
<%= sanitize(t("verification.residence.new.document_number_help_text")) %> | ||
</div> | ||
|
||
<%= f.text_field :document_number, label: false %> | ||
</div> | ||
</div> | ||
|
||
<div class="row"> | ||
<%= fields_for @sms do |s| %> | ||
|
||
<div class="small-12 medium-4 column"> | ||
<%= s.label :phone, t("verification.sms.new.phone"), class: "inline-block" %> | ||
<p class="help-text" id="phone-text-help"><%= t("verification.sms.new.phone_note") %></p> | ||
<%= s.telephone_field :phone, label: false, | ||
aria: { describedby: "phone-help-text" } | ||
%> | ||
</div> | ||
<% end %> | ||
</div> | ||
|
||
<div class="small-12 mt-3"> | ||
<%= f.check_box :terms_of_service, | ||
label: t("verification.residence.new.accept_terms_adult") %> | ||
|
||
<%= f.check_box :adult, | ||
label: t("verification.residence.new.accept_terms_resident", | ||
residence: Rails.configuration.deploy['city']) %> | ||
|
||
<%= f.check_box :resident, | ||
label: t("verification.residence.new.accept_terms_terms", | ||
terms_url: link_to(t("verification.residence.new.terms"), "/census_terms", | ||
title: t("shared.target_blank"), | ||
target: "_blank")) %> | ||
</div> | ||
|
||
<div class="small-12 medium-3 clear"> | ||
<%= f.submit t("verification.residence.new.verify_residence"), | ||
id: "new_residence_submit", | ||
class: "button success expanded" %> | ||
</div> | ||
<% end %> | ||
</div> | ||
</div> |
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,5 +1,7 @@ | ||
module Consul | ||
class Application < Rails::Application | ||
config.i18n.default_locale = :en | ||
config.deploy = config_for(:deploy) | ||
config.action_view.cache_template_loading = false | ||
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 |
---|---|---|
@@ -0,0 +1,11 @@ | ||
development: | ||
city: Brașov | ||
support_email: [email protected] | ||
|
||
staging: | ||
city: Brașov | ||
support_email: [email protected] | ||
|
||
production: | ||
city: Brașov | ||
support_email: [email protected] |
Oops, something went wrong.