Skip to content

Commit 0cc375f

Browse files
authored
Merge pull request #309 from Trim/fix-link-validation
link and bookmark model validate URL
2 parents 7e89d77 + 2a5cf60 commit 0cc375f

File tree

12 files changed

+93
-28
lines changed

12 files changed

+93
-28
lines changed

app/assets/javascripts/edition_in_place.coffee

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ class EditionInPlace
4242
false
4343

4444
error: =>
45+
try
46+
error = @el.find("ul.error")
47+
response = $.parseJSON(@xhr.responseText)
48+
messages = []
49+
for attribute, errors of response.errors
50+
for message in errors
51+
messages.push(message)
52+
if messages.length == 1
53+
error.text("Erreur : " + messages[0])
54+
else
55+
error.text("Erreurs :")
56+
for message in messages
57+
error.append($("<li>").append(message))
58+
error.show()
4559
@el.trigger "in_place:error", @xhr
4660
@xhr = null
4761

app/assets/stylesheets/parts/content.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ body#news-revision #contents,
1313
body#boards-show #contents,
1414
body#stylesheets-edit #contents,
1515
body#wiki_pages-changes #contents,
16-
body#admin-index #container > ul {
16+
body#admin-index #container > ul,
17+
#redaction #new_link,
18+
#redaction .edit_link {
1719
display: block;
1820
background: white;
1921
padding: 10px $PX_PAD_NODE 10px $PX_PAD_NODE;

app/assets/stylesheets/parts/redaction.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,10 @@ body#redaction-index {
503503
}
504504
}
505505
}
506+
#new_link,
507+
.edit_link {
508+
padding: 5px;
509+
}
506510
input#link_title {
507511
width: 100%; // this rule force the input to not enlarge the #edition flex box
508512
}

app/controllers/redaction/links_controller.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,29 @@ def new
1212
def create
1313
@link.attributes = link_params
1414
@link.user = current_user
15-
@link.save
16-
render partial: 'button'
15+
if @link.save
16+
render partial: 'button'
17+
else
18+
render status: :unprocessable_entity, json: { errors: @link.errors.as_json }
19+
end
1720
end
1821

1922
def edit
2023
if @link.lock_by(current_user)
2124
render partial: 'form'
2225
else
23-
render status: :forbidden, text: "Désolé, #{@link.locker} est déjà en train de modifier ce lien !"
26+
render status: :forbidden, plain: "Désolé, #{@link.locker} est déjà en train de modifier ce lien !"
2427
end
2528
end
2629

2730
def update
2831
@link.attributes = link_params
2932
@link.update_by(current_user)
30-
render @link
33+
if @link.destroyed? || @link.save
34+
render @link
35+
else
36+
render status: :unprocessable_entity, json: { errors: @link.errors.as_json }
37+
end
3138
end
3239

3340
def unlock

app/controllers/redaction/news_controller.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,18 @@ def reorganize
5959
@news.put_paragraphs_together
6060
render :reorganize, layout: "chat_n_edit"
6161
else
62-
render status: :forbidden, text: "Désolé, un verrou a déjà été posé sur cette dépêche !"
62+
render status: :forbidden, plain: "Désolé, un verrou a déjà été posé sur cette dépêche !"
6363
end
6464
end
6565

6666
def reorganized
6767
@news.editor = current_account
68-
@news.reorganize news_params
69-
redirect_to [@news.draft? ? :redaction : :moderation, @news]
68+
if @news.reorganize news_params
69+
redirect_to [@news.draft? ? :redaction : :moderation, @news]
70+
else
71+
load_board
72+
render :reorganize, layout: "chat_n_edit"
73+
end
7074
end
7175

7276
def followup

app/controllers/redaction/paragraphs_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def edit
2525
if @paragraph.lock_by(current_user)
2626
render partial: 'form'
2727
else
28-
render status: :forbidden, text: "Désolé, #{@paragraph.locker} est déjà en train de modifier ce paragraphe !"
28+
render status: :forbidden, plain: "Désolé, #{@paragraph.locker} est déjà en train de modifier ce paragraphe !"
2929
end
3030
end
3131

app/models/bookmark.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Bookmark < Content
2626
validates :title, presence: { message: "Le titre est obligatoire" },
2727
length: { maximum: 100, message: "Le titre est trop long" }
2828
validates :link, presence: { message: "Vous ne pouvez pas poster un lien vide" },
29+
http_url: { message: "Le lien n'est pas valide" },
2930
length: { maximum: 255, message: "Le lien est trop long" }
3031

3132
def create_node(attrs={})

app/models/link.rb

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ class Link < ActiveRecord::Base
2626

2727
validates :title, presence: { message: "Un lien doit obligatoirement avoir un titre" },
2828
length: { maximum: 100, message: "Le titre est trop long" }
29-
validates :url, presence: { message: "Un lien doit obligatoirement avoir une adresse" },
29+
validates :url, http_url: { protocols: PROTOCOLS, message: "L'adresse n'est pas valide" },
30+
presence: { message: "Un lien doit obligatoirement avoir une adresse" },
3031
length: { maximum: 255, message: "L’adresse est trop longue" }
31-
validate :authorized_protocol
3232

3333
def url=(raw)
3434
raw.strip!
@@ -39,17 +39,9 @@ def url=(raw)
3939
uri = URI.parse(raw)
4040
end
4141
write_attribute :url, uri.to_s
42-
end
43-
44-
def authorized_protocol
45-
if url.blank?
46-
errors.add(:url, "L’adresse est obligatoire")
47-
else
48-
uri = URI.parse(url)
49-
return true if PROTOCOLS.include?(uri.scheme)
50-
return true if uri.scheme.nil? && uri.host == MY_DOMAIN
51-
errors.add(:url, "L’adresse d’un lien n’est pas valide")
52-
end
42+
# Let raw value if error when parsed, HttpUrlValidator will manage it
43+
rescue URI::InvalidURIError
44+
write_attribute :url, raw
5345
end
5446

5547
### Behaviour ###

app/models/news.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,20 @@ def nb_editors
260260
end
261261

262262
def reorganize(params)
263-
Paragraph.where(news_id: self.id).delete_all
264-
self.attributes = params
265-
create_parts
266-
save
267-
unlock
263+
reorganized = false
264+
self.transaction do
265+
Paragraph.where(news_id: self.id).delete_all
266+
self.attributes = params
267+
create_parts
268+
# Let commit transaction only if save is successful so version will be well created
269+
if save
270+
reorganized = true
271+
else
272+
raise ActiveRecord::Rollback
273+
end
274+
end
275+
unlock if reorganized
276+
reorganized
268277
end
269278

270279
### Associated node ###
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Validate if a value is a HTTP url
2+
class HttpUrlValidator < ActiveModel::EachValidator
3+
def validate_each(record, attribute, value)
4+
if value.present? && not(valid?(value, options))
5+
record.errors.add attribute, (options[:message] || "n'est pas une URL HTTP valide")
6+
end
7+
end
8+
9+
private
10+
11+
def valid?(value, options)
12+
uri = URI.parse(value)
13+
if uri.scheme.blank? && uri.host.blank?
14+
value = "http://#{value}"
15+
uri = URI.parse(value)
16+
end
17+
if options.has_key?(:protocols)
18+
return true if options[:protocols].include?(uri.scheme)
19+
end
20+
uri.scheme.nil? && uri.host == MY_DOMAIN
21+
rescue URI::InvalidURIError
22+
false
23+
end
24+
end

0 commit comments

Comments
 (0)