module CamaleonCms::CaptchaHelper
# build a captcha image
# len: Number or characters to include in captcha (default 5)
def cama_captcha_build(len = 5)
img = MiniMagick::Image.open(File.join($camaleon_engine_dir.present? ? $camaleon_engine_dir : Rails.root.to_s, "lib", "captcha", "captcha_#{rand(12)}.jpg").to_s)
text = cama_rand_str(len)
session[:cama_captcha] = [] unless session[:cama_captcha].present?
session[:cama_captcha] << text
img.combine_options do |c|
c.gravity 'Center'
c.fill("#FFFFFF")
c.draw "text 0,5 #{text}"
c.font File.join($camaleon_engine_dir.present? ? $camaleon_engine_dir : Rails.root.to_s, "lib", "captcha", "bumpyroad.ttf")
c.pointsize '30'
end
img
end
# build a captcha tag (image with captcha)
# img_args: attributes for image_tag
# input_args: attributes for input field
def cama_captcha_tag(len = 5, img_args = {alt: ""}, input_args = {}, bootstrap_group_mode = false)
input_args[:placeholder] = I18n.t('camaleon_cms.captcha_placeholder', default: 'Please enter the text of the image') unless input_args[:placeholder].present?
img_args["onclick"] = "this.src = \"#{cama_captcha_url(len: len)}\"+\"&t=\"+(new Date().getTime());"
img = ""
input = ""
if bootstrap_group_mode
"
#{img}#{input}
"
else
"
#{img}#{input}
"
end
end
# verify captcha value
def cama_captcha_verified?
(session[:cama_captcha] || []).include?((params[:cama_captcha] || params[:captcha]).to_s.upcase)
end
#************************* captcha in attack helpers ***************************#
# check if the current visitor was submitted 5+ times
# key: a string to represent a url or form view
# key must be the same as the form "captcha_tags_if_under_attack(key, ...)"
def cama_captcha_under_attack?(key)
session["cama_captcha_#{key}"] ||= 0
session["cama_captcha_#{key}"].to_i > current_site.get_option("max_try_attack", 5).to_i
end
# verify captcha values if this key is under attack
# key: a string to represent a url or form view
def captcha_verify_if_under_attack(key)
res = cama_captcha_under_attack?(key) ? cama_captcha_verified? : true
session["cama_captcha_#{key}"] = 0 if cama_captcha_verified?
res
end
# increment attempts for key by 1
def cama_captcha_increment_attack(key)
session["cama_captcha_#{key}"] ||= 0
session["cama_captcha_#{key}"] = session["cama_captcha_#{key}"].to_i + 1
end
# reset the attacks counter for key
# key: a string to represent a url or form view
def cama_captcha_reset_attack(key)
session["cama_captcha_#{key}"] = 0
end
# return a number of attempts for key
# key: a string to represent a url or form view
def cama_captcha_total_attacks(key)
session["cama_captcha_#{key}"] ||= 0
end
# show captcha if under attack
# key: a string to represent a url or form view
def cama_captcha_tags_if_under_attack(key, captcha_parmas = [5, {}, {class: "form-control required"}])
cama_captcha_tag(*captcha_parmas) if cama_captcha_under_attack?(key)
end
private
# generate random string for captcha
# len: length of characters, default 6
def cama_rand_str(len=6)
alphabets = [('A'..'Z').to_a].flatten!
alphanumerics = [('A'..'Z').to_a,('1'..'9').to_a].flatten!
str = alphabets[rand(alphabets.size)]
(len.to_i - 1).times do
str << alphanumerics[rand(alphanumerics.size)]
end
str
end
end