antispam 0.2.0 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -20
- data/README.md +141 -128
- data/Rakefile +18 -18
- data/app/assets/config/antispam_manifest.js +1 -1
- data/app/assets/stylesheets/antispam/application.css +15 -15
- data/app/assets/stylesheets/antispam/blocks.css +4 -4
- data/app/assets/stylesheets/antispam/challenges.css +4 -4
- data/app/assets/stylesheets/antispam/clears.css +4 -4
- data/app/assets/stylesheets/scaffold.css +80 -80
- data/app/controllers/antispam/application_controller.rb +11 -11
- data/app/controllers/antispam/blocks_controller.rb +28 -28
- data/app/controllers/antispam/challenges_controller.rb +50 -50
- data/app/controllers/antispam/clears_controller.rb +28 -28
- data/app/controllers/antispam/validate_controller.rb +12 -12
- data/app/helpers/antispam/application_helper.rb +4 -4
- data/app/helpers/antispam/blocks_helper.rb +4 -4
- data/app/helpers/antispam/challenges_helper.rb +4 -4
- data/app/helpers/antispam/clears_helper.rb +4 -4
- data/app/jobs/antispam/application_job.rb +4 -4
- data/app/mailers/antispam/application_mailer.rb +6 -6
- data/app/models/antispam/application_record.rb +5 -5
- data/app/models/antispam/block.rb +4 -4
- data/app/models/antispam/challenge.rb +26 -26
- data/app/models/antispam/clear.rb +4 -4
- data/app/models/antispam/ip.rb +11 -6
- data/app/views/antispam/blocks/index.html.erb +38 -38
- data/app/views/antispam/blocks/show.html.erb +24 -24
- data/app/views/antispam/challenges/_form.html.erb +32 -32
- data/app/views/antispam/challenges/edit.html.erb +6 -6
- data/app/views/antispam/challenges/index.html.erb +31 -31
- data/app/views/antispam/challenges/new.html.erb +5 -5
- data/app/views/antispam/challenges/show.html.erb +19 -19
- data/app/views/antispam/clears/index.html.erb +32 -32
- data/app/views/antispam/clears/show.html.erb +29 -29
- data/app/views/antispam/validate/index.html.erb +16 -14
- data/app/views/layouts/antispam/application.html.erb +25 -15
- data/config/routes.rb +7 -7
- data/db/migrate/20210130213708_create_antispam_ips.rb +12 -12
- data/db/migrate/20210130214835_create_antispam_challenges.rb +11 -11
- data/db/migrate/20210130234107_create_antispam_blocks.rb +12 -12
- data/db/migrate/20210130235537_create_antispam_clears.rb +13 -13
- data/db/migrate/20210131165122_add_threat_to_antispam_blocks.rb +5 -5
- data/lib/antispam/blacklists/httpbl.rb +49 -49
- data/lib/antispam/checker.rb +30 -30
- data/lib/antispam/engine.rb +5 -5
- data/lib/antispam/results.rb +18 -18
- data/lib/antispam/spamcheckers/defendium.rb +29 -29
- data/lib/antispam/tools.rb +59 -59
- data/lib/antispam/version.rb +3 -3
- data/lib/antispam.rb +21 -17
- data/lib/tasks/antispam_tasks.rake +4 -4
- metadata +6 -6
@@ -1,28 +1,28 @@
|
|
1
|
-
require_dependency "antispam/application_controller"
|
2
|
-
|
3
|
-
module Antispam
|
4
|
-
class BlocksController < ApplicationController
|
5
|
-
before_action :must_be_admin
|
6
|
-
before_action :set_block, only: [:show]
|
7
|
-
|
8
|
-
# GET /blocks
|
9
|
-
def index
|
10
|
-
@blocks = Block.all
|
11
|
-
end
|
12
|
-
|
13
|
-
# GET /blocks/1
|
14
|
-
def show
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
# Use callbacks to share common setup or constraints between actions.
|
19
|
-
def set_block
|
20
|
-
@block = Block.find(params[:id])
|
21
|
-
end
|
22
|
-
|
23
|
-
# Only allow a list of trusted parameters through.
|
24
|
-
def block_params
|
25
|
-
params.require(:block).permit(:ip, :provider, :controllername, :actionname)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
1
|
+
require_dependency "antispam/application_controller"
|
2
|
+
|
3
|
+
module Antispam
|
4
|
+
class BlocksController < ApplicationController
|
5
|
+
before_action :must_be_admin
|
6
|
+
before_action :set_block, only: [:show]
|
7
|
+
|
8
|
+
# GET /blocks
|
9
|
+
def index
|
10
|
+
@blocks = Block.all
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /blocks/1
|
14
|
+
def show
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
# Use callbacks to share common setup or constraints between actions.
|
19
|
+
def set_block
|
20
|
+
@block = Block.find(params[:id])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Only allow a list of trusted parameters through.
|
24
|
+
def block_params
|
25
|
+
params.require(:block).permit(:ip, :provider, :controllername, :actionname)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,50 +1,50 @@
|
|
1
|
-
require_dependency "antispam/application_controller"
|
2
|
-
|
3
|
-
module Antispam
|
4
|
-
class ChallengesController < ApplicationController
|
5
|
-
before_action :set_challenge, only: [:show, :edit, :update
|
6
|
-
|
7
|
-
# GET /challenges/1
|
8
|
-
def show
|
9
|
-
respond_to do |format|
|
10
|
-
format.jpeg do
|
11
|
-
image = @challenge.get_image
|
12
|
-
render content_type: 'image/jpeg', plain: image.jpegsave_buffer
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# GET /challenges/new
|
18
|
-
def new
|
19
|
-
# use in the future for changing code
|
20
|
-
head :ok
|
21
|
-
end
|
22
|
-
|
23
|
-
# PATCH/PUT /challenges/1
|
24
|
-
def update
|
25
|
-
if @challenge.validate?(params[:challenge][:answer])
|
26
|
-
a = Antispam::Ip.find_or_create_by(address: request.remote_ip, provider: 'httpbl')
|
27
|
-
before = a.threat
|
28
|
-
a.threat = [(a.threat || 0) - 25, 0].max
|
29
|
-
c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Passed', threat_before: before, threat_after: a.threat)
|
30
|
-
a.expires_at = 1.hour.from_now
|
31
|
-
a.save
|
32
|
-
redirect_to '/'
|
33
|
-
else
|
34
|
-
c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Failed')
|
35
|
-
redirect_to '/antispam/validate', notice: 'Invalid answer.'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
# Use callbacks to share common setup or constraints between actions.
|
41
|
-
def set_challenge
|
42
|
-
@challenge = Challenge.find(params[:id])
|
43
|
-
end
|
44
|
-
|
45
|
-
# Only allow a list of trusted parameters through.
|
46
|
-
def challenge_params
|
47
|
-
params.require(:challenge).permit(:answer, :code)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
1
|
+
require_dependency "antispam/application_controller"
|
2
|
+
|
3
|
+
module Antispam
|
4
|
+
class ChallengesController < ApplicationController
|
5
|
+
before_action :set_challenge, only: [:show, :edit, :update]
|
6
|
+
|
7
|
+
# GET /challenges/1
|
8
|
+
def show
|
9
|
+
respond_to do |format|
|
10
|
+
format.jpeg do
|
11
|
+
image = @challenge.get_image
|
12
|
+
render content_type: 'image/jpeg', plain: image.jpegsave_buffer
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# GET /challenges/new
|
18
|
+
def new
|
19
|
+
# use in the future for changing code
|
20
|
+
head :ok
|
21
|
+
end
|
22
|
+
|
23
|
+
# PATCH/PUT /challenges/1
|
24
|
+
def update
|
25
|
+
if @challenge.validate?(params[:challenge][:answer])
|
26
|
+
a = Antispam::Ip.find_or_create_by(address: request.remote_ip, provider: 'httpbl')
|
27
|
+
before = a.threat
|
28
|
+
a.threat = [(a.threat || 0) - 25, 0].max
|
29
|
+
c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Passed', threat_before: before, threat_after: a.threat)
|
30
|
+
a.expires_at = 1.hour.from_now
|
31
|
+
a.save
|
32
|
+
redirect_to '/'
|
33
|
+
else
|
34
|
+
c = Clear.create(ip: request.remote_ip, answer: params[:challenge][:answer], result: 'Failed')
|
35
|
+
redirect_to '/antispam/validate', notice: 'Invalid answer.'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
# Use callbacks to share common setup or constraints between actions.
|
41
|
+
def set_challenge
|
42
|
+
@challenge = Challenge.find(params[:id])
|
43
|
+
end
|
44
|
+
|
45
|
+
# Only allow a list of trusted parameters through.
|
46
|
+
def challenge_params
|
47
|
+
params.require(:challenge).permit(:answer, :code)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
require_dependency "antispam/application_controller"
|
2
|
-
|
3
|
-
module Antispam
|
4
|
-
class ClearsController < ApplicationController
|
5
|
-
before_action :must_be_admin
|
6
|
-
before_action :set_clear, only: [:show, :edit, :update, :destroy]
|
7
|
-
|
8
|
-
# GET /clears
|
9
|
-
def index
|
10
|
-
@clears = Clear.all
|
11
|
-
end
|
12
|
-
|
13
|
-
# GET /clears/1
|
14
|
-
def show
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
# Use callbacks to share common setup or constraints between actions.
|
19
|
-
def set_clear
|
20
|
-
@clear = Clear.find(params[:id])
|
21
|
-
end
|
22
|
-
|
23
|
-
# Only allow a list of trusted parameters through.
|
24
|
-
def clear_params
|
25
|
-
params.require(:clear).permit(:ip, :result, :answer, :threat_before, :threat_after)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
1
|
+
require_dependency "antispam/application_controller"
|
2
|
+
|
3
|
+
module Antispam
|
4
|
+
class ClearsController < ApplicationController
|
5
|
+
before_action :must_be_admin
|
6
|
+
before_action :set_clear, only: [:show, :edit, :update, :destroy]
|
7
|
+
|
8
|
+
# GET /clears
|
9
|
+
def index
|
10
|
+
@clears = Clear.all
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /clears/1
|
14
|
+
def show
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
# Use callbacks to share common setup or constraints between actions.
|
19
|
+
def set_clear
|
20
|
+
@clear = Clear.find(params[:id])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Only allow a list of trusted parameters through.
|
24
|
+
def clear_params
|
25
|
+
params.require(:clear).permit(:ip, :result, :answer, :threat_before, :threat_after)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_dependency "antispam/application_controller"
|
2
|
-
|
3
|
-
module Antispam
|
4
|
-
class ValidateController < ApplicationController
|
5
|
-
def index
|
6
|
-
respond_to do |format|
|
7
|
-
format.html
|
8
|
-
format.js { render js: 'window.location = "/antispam/validate"'}
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
1
|
+
require_dependency "antispam/application_controller"
|
2
|
+
|
3
|
+
module Antispam
|
4
|
+
class ValidateController < ApplicationController
|
5
|
+
def index
|
6
|
+
respond_to do |format|
|
7
|
+
format.html
|
8
|
+
format.js { render js: 'window.location = "/antispam/validate"'}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
module ApplicationHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
module ApplicationHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
module BlocksHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
module BlocksHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
module ChallengesHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
module ChallengesHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
module ClearsHelper
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
module ClearsHelper
|
3
|
+
end
|
4
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
class ApplicationJob < ActiveJob::Base
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class ApplicationJob < ActiveJob::Base
|
3
|
+
end
|
4
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
module Antispam
|
2
|
-
class ApplicationMailer < ActionMailer::Base
|
3
|
-
default from: 'from@example.com'
|
4
|
-
layout 'mailer'
|
5
|
-
end
|
6
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class ApplicationMailer < ActionMailer::Base
|
3
|
+
default from: 'from@example.com'
|
4
|
+
layout 'mailer'
|
5
|
+
end
|
6
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module Antispam
|
2
|
-
class ApplicationRecord < ActiveRecord::Base
|
3
|
-
self.abstract_class = true
|
4
|
-
end
|
5
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class ApplicationRecord < ActiveRecord::Base
|
3
|
+
self.abstract_class = true
|
4
|
+
end
|
5
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
class Block < ApplicationRecord
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class Block < ApplicationRecord
|
3
|
+
end
|
4
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
module Antispam
|
2
|
-
class Challenge < ApplicationRecord
|
3
|
-
before_create :generate
|
4
|
-
|
5
|
-
def generate
|
6
|
-
self.question = create_string
|
7
|
-
self.answer = self.question
|
8
|
-
end
|
9
|
-
def create_string
|
10
|
-
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
|
11
|
-
(0...8).map { o[rand(o.length)] }.join
|
12
|
-
end
|
13
|
-
def get_image
|
14
|
-
require "image_processing/vips"
|
15
|
-
image = Vips::Image.text(self.answer, dpi: 300)
|
16
|
-
image.draw_line(255, 5+rand(20).to_i, 5+rand(20).to_i, 150+rand(50).to_i, 10+rand(10).to_i)
|
17
|
-
end
|
18
|
-
def validate?(check)
|
19
|
-
return false if self.answer.nil?
|
20
|
-
result = false
|
21
|
-
result = true if self.answer.downcase == check.downcase
|
22
|
-
self.update_column(:answer,nil)
|
23
|
-
return result
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class Challenge < ApplicationRecord
|
3
|
+
before_create :generate
|
4
|
+
|
5
|
+
def generate
|
6
|
+
self.question = create_string
|
7
|
+
self.answer = self.question
|
8
|
+
end
|
9
|
+
def create_string
|
10
|
+
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
|
11
|
+
(0...8).map { o[rand(o.length)] }.join
|
12
|
+
end
|
13
|
+
def get_image
|
14
|
+
require "image_processing/vips"
|
15
|
+
image = Vips::Image.text(self.answer, dpi: 300)
|
16
|
+
image.draw_line(255, 5+rand(20).to_i, 5+rand(20).to_i, 150+rand(50).to_i, 10+rand(10).to_i)
|
17
|
+
end
|
18
|
+
def validate?(check)
|
19
|
+
return false if self.answer.nil?
|
20
|
+
result = false
|
21
|
+
result = true if self.answer.downcase == check.downcase
|
22
|
+
self.update_column(:answer,nil)
|
23
|
+
return result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Antispam
|
2
|
-
class Clear < ApplicationRecord
|
3
|
-
end
|
4
|
-
end
|
1
|
+
module Antispam
|
2
|
+
class Clear < ApplicationRecord
|
3
|
+
end
|
4
|
+
end
|
data/app/models/antispam/ip.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
module Antispam
|
2
|
-
class Ip < ApplicationRecord
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Antispam
|
2
|
+
class Ip < ApplicationRecord
|
3
|
+
after_initialize :set_default_expires_at
|
4
|
+
def expired?
|
5
|
+
self.expires_at < Time.now
|
6
|
+
end
|
7
|
+
private
|
8
|
+
def set_default_expires_at
|
9
|
+
self.expires_at ||= 24.hours.from_now
|
10
|
+
end
|
11
|
+
end
|
7
12
|
end
|
@@ -1,39 +1,39 @@
|
|
1
|
-
<p id="notice"><%= notice %></p>
|
2
|
-
|
3
|
-
<div class="row">
|
4
|
-
<div class="cx">
|
5
|
-
<h1>Blocks</h1>
|
6
|
-
|
7
|
-
<table>
|
8
|
-
<thead>
|
9
|
-
<tr>
|
10
|
-
<th>Ip</th>
|
11
|
-
<th>Provider</th>
|
12
|
-
<th>Controllername</th>
|
13
|
-
<th>Actionname</th>
|
14
|
-
<th>Threat</th>
|
15
|
-
<th colspan="3"></th>
|
16
|
-
</tr>
|
17
|
-
</thead>
|
18
|
-
|
19
|
-
<tbody>
|
20
|
-
<% Antispam::Block.all.order(created_at: :desc).limit(50).each do |block| %>
|
21
|
-
<tr>
|
22
|
-
<td><%= block.ip %></td>
|
23
|
-
<td><%= block.provider %></td>
|
24
|
-
<td><%= block.controllername %></td>
|
25
|
-
<td><%= block.actionname %></td>
|
26
|
-
<td><%= block.threat %></td>
|
27
|
-
<td><%= time_ago_in_words block.created_at %> ago</td>
|
28
|
-
<!-- <td><%#= link_to 'Show', block %></td>-->
|
29
|
-
<!-- <td><%#= link_to 'Edit', edit_block_path(block) %></td>-->
|
30
|
-
<!-- <td><%#= link_to 'Destroy', block, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
|
31
|
-
</tr>
|
32
|
-
<% end %>
|
33
|
-
</tbody>
|
34
|
-
</table>
|
35
|
-
</div>
|
36
|
-
<div class="cx">
|
37
|
-
<%= render template: '/antispam/clears/index', formats: :html %>
|
38
|
-
</div>
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<div class="row">
|
4
|
+
<div class="cx">
|
5
|
+
<h1>Blocks</h1>
|
6
|
+
|
7
|
+
<table>
|
8
|
+
<thead>
|
9
|
+
<tr>
|
10
|
+
<th>Ip</th>
|
11
|
+
<th>Provider</th>
|
12
|
+
<th>Controllername</th>
|
13
|
+
<th>Actionname</th>
|
14
|
+
<th>Threat</th>
|
15
|
+
<th colspan="3"></th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
|
19
|
+
<tbody>
|
20
|
+
<% Antispam::Block.all.order(created_at: :desc).limit(50).each do |block| %>
|
21
|
+
<tr>
|
22
|
+
<td><%= block.ip %></td>
|
23
|
+
<td><%= block.provider %></td>
|
24
|
+
<td><%= block.controllername %></td>
|
25
|
+
<td><%= block.actionname %></td>
|
26
|
+
<td><%= block.threat %></td>
|
27
|
+
<td><%= time_ago_in_words block.created_at %> ago</td>
|
28
|
+
<!-- <td><%#= link_to 'Show', block %></td>-->
|
29
|
+
<!-- <td><%#= link_to 'Edit', edit_block_path(block) %></td>-->
|
30
|
+
<!-- <td><%#= link_to 'Destroy', block, method: :delete, data: { confirm: 'Are you sure?' } %></td>-->
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
</div>
|
36
|
+
<div class="cx">
|
37
|
+
<%= render template: '/antispam/clears/index', formats: :html %>
|
38
|
+
</div>
|
39
39
|
</div>
|
@@ -1,24 +1,24 @@
|
|
1
|
-
<p id="notice"><%= notice %></p>
|
2
|
-
|
3
|
-
<p>
|
4
|
-
<strong>Ip:</strong>
|
5
|
-
<%= @block.ip %>
|
6
|
-
</p>
|
7
|
-
|
8
|
-
<p>
|
9
|
-
<strong>Provider:</strong>
|
10
|
-
<%= @block.provider %>
|
11
|
-
</p>
|
12
|
-
|
13
|
-
<p>
|
14
|
-
<strong>Controllername:</strong>
|
15
|
-
<%= @block.controllername %>
|
16
|
-
</p>
|
17
|
-
|
18
|
-
<p>
|
19
|
-
<strong>Actionname:</strong>
|
20
|
-
<%= @block.actionname %>
|
21
|
-
</p>
|
22
|
-
|
23
|
-
<%= link_to 'Edit', edit_block_path(@block) %> |
|
24
|
-
<%= link_to 'Back', blocks_path %>
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<strong>Ip:</strong>
|
5
|
+
<%= @block.ip %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<strong>Provider:</strong>
|
10
|
+
<%= @block.provider %>
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<p>
|
14
|
+
<strong>Controllername:</strong>
|
15
|
+
<%= @block.controllername %>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
<strong>Actionname:</strong>
|
20
|
+
<%= @block.actionname %>
|
21
|
+
</p>
|
22
|
+
|
23
|
+
<%= link_to 'Edit', edit_block_path(@block) %> |
|
24
|
+
<%= link_to 'Back', blocks_path %>
|
@@ -1,32 +1,32 @@
|
|
1
|
-
<%= form_with(model: challenge) do |form| %>
|
2
|
-
<% if challenge.errors.any? %>
|
3
|
-
<div id="error_explanation">
|
4
|
-
<h2><%= pluralize(challenge.errors.count, "error") %> prohibited this challenge from being saved:</h2>
|
5
|
-
|
6
|
-
<ul>
|
7
|
-
<% challenge.errors.each do |error| %>
|
8
|
-
<li><%= error.full_message %></li>
|
9
|
-
<% end %>
|
10
|
-
</ul>
|
11
|
-
</div>
|
12
|
-
<% end %>
|
13
|
-
|
14
|
-
<div class="field">
|
15
|
-
<%= form.label :question %>
|
16
|
-
<%= form.text_field :question %>
|
17
|
-
</div>
|
18
|
-
|
19
|
-
<div class="field">
|
20
|
-
<%= form.label :answer %>
|
21
|
-
<%= form.text_field :answer %>
|
22
|
-
</div>
|
23
|
-
|
24
|
-
<div class="field">
|
25
|
-
<%= form.label :code %>
|
26
|
-
<%= form.text_field :code %>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
<div class="actions">
|
30
|
-
<%= form.submit %>
|
31
|
-
</div>
|
32
|
-
<% end %>
|
1
|
+
<%= form_with(model: challenge) do |form| %>
|
2
|
+
<% if challenge.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(challenge.errors.count, "error") %> prohibited this challenge from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% challenge.errors.each do |error| %>
|
8
|
+
<li><%= error.full_message %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= form.label :question %>
|
16
|
+
<%= form.text_field :question %>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="field">
|
20
|
+
<%= form.label :answer %>
|
21
|
+
<%= form.text_field :answer %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="field">
|
25
|
+
<%= form.label :code %>
|
26
|
+
<%= form.text_field :code %>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div class="actions">
|
30
|
+
<%= form.submit %>
|
31
|
+
</div>
|
32
|
+
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
|
-
<h1>Editing Challenge</h1>
|
2
|
-
|
3
|
-
<%= render 'form', challenge: @challenge %>
|
4
|
-
|
5
|
-
<%= link_to 'Show', @challenge %> |
|
6
|
-
<%= link_to 'Back', challenges_path %>
|
1
|
+
<h1>Editing Challenge</h1>
|
2
|
+
|
3
|
+
<%= render 'form', challenge: @challenge %>
|
4
|
+
|
5
|
+
<%= link_to 'Show', @challenge %> |
|
6
|
+
<%= link_to 'Back', challenges_path %>
|