[california/wip/731543-attendees: 12/12] Input validation
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/731543-attendees: 12/12] Input validation
- Date: Thu, 30 Oct 2014 01:54:04 +0000 (UTC)
commit df2c17c20c0b0432be716217f5861bfca21ae5ad
Author: Jim Nelson <jim yorba org>
Date: Wed Oct 29 18:52:26 2014 -0700
Input validation
src/collection/collection-iterable.vala | 17 +++++++++++++++++
src/host/host-create-update-event.vala | 12 ++++++++++++
src/host/host.vala | 2 ++
src/rc/create-update-event.ui | 4 ++--
src/util/util-mailto.vala | 18 ------------------
src/util/util-uri.vala | 19 +++++++++++++++++++
src/util/util.vala | 2 ++
7 files changed, 54 insertions(+), 20 deletions(-)
---
diff --git a/src/collection/collection-iterable.vala b/src/collection/collection-iterable.vala
index d51e82d..3ee25ba 100644
--- a/src/collection/collection-iterable.vala
+++ b/src/collection/collection-iterable.vala
@@ -111,6 +111,11 @@ public class Iterable<G> : Object {
public delegate void Iterate<G>(G element);
/**
+ * For simple transformation of elements in the { link Iterable}.
+ */
+ public delegate G Transform<G>(G element);
+
+ /**
* For mapping a single value of one type to multiple values of another.
*/
public delegate Gee.Collection<A> Bloom<A, G>(G element);
@@ -166,6 +171,18 @@ public class Iterable<G> : Object {
return new Iterable<G>(list.iterator());
}
+ /**
+ * Like { link iterate}, called for each element, but adds the returned (possibly transformed)
+ * element.
+ */
+ public Iterable<G> transform(Transform<G> transformer) {
+ Gee.ArrayList<G> list = new Gee.ArrayList<G>();
+ foreach (G g in this)
+ list.add(transformer(g));
+
+ return new Iterable<G>(list.iterator());
+ }
+
public Iterable<A> map<A>(Gee.MapFunc<A, G> f) {
return new Iterable<A>(i.map<A>(f));
}
diff --git a/src/host/host-create-update-event.vala b/src/host/host-create-update-event.vala
index 68aeea1..922d8c6 100644
--- a/src/host/host-create-update-event.vala
+++ b/src/host/host-create-update-event.vala
@@ -94,6 +94,9 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
update_this_button.clicked.connect(on_update_this_button_clicked);
cancel_recurring_button.clicked.connect(on_cancel_recurring_button_clicked);
+ attendees_entry.bind_property("text", accept_button, "sensitive",
+ BindingFlags.SYNC_CREATE, transform_attendees_to_accept);
+
rotating_button_box.pack_end(FAMILY_NORMAL, cancel_button);
rotating_button_box.pack_end(FAMILY_NORMAL, accept_button);
@@ -124,6 +127,15 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
return true;
}
+ private bool transform_attendees_to_accept(Binding binding, Value source_value, ref Value target_value) {
+ target_value = from_array<string>(attendees_entry.text.split_set(" \t,;"))
+ .transform(str => str.strip())
+ .filter(str => !String.is_empty(str))
+ .all(str => URI.is_valid_mailbox(str));
+
+ return true;
+ }
+
public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
// if no message, leave everything as it is
if (message == null)
diff --git a/src/host/host.vala b/src/host/host.vala
index 0e5d330..6e075a6 100644
--- a/src/host/host.vala
+++ b/src/host/host.vala
@@ -24,12 +24,14 @@ public void init() throws Error {
Calendar.init();
Toolkit.init();
Component.init();
+ Util.init();
}
public void terminate() {
if (!Unit.do_terminate(ref init_count))
return;
+ Util.terminate();
Component.terminate();
View.terminate();
Backing.terminate();
diff --git a/src/rc/create-update-event.ui b/src/rc/create-update-event.ui
index 4e381b8..26f672c 100644
--- a/src/rc/create-update-event.ui
+++ b/src/rc/create-update-event.ui
@@ -328,10 +328,10 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">For example:
-alice example com, Bob <bob example com></property>
+alice example com, bob example com</property>
<property name="activates_default">True</property>
<property name="caps_lock_warning">False</property>
- <property name="placeholder_text" translatable="yes">Email addresses separated by commas</property>
+ <property name="placeholder_text" translatable="yes">Email address(es)</property>
</object>
<packing>
<property name="left_attach">1</property>
diff --git a/src/util/util-uri.vala b/src/util/util-uri.vala
index 83390ed..0a61e1a 100644
--- a/src/util/util-uri.vala
+++ b/src/util/util-uri.vala
@@ -14,6 +14,18 @@ errordomain URIError {
namespace California.URI {
+private Regex email_regex;
+
+internal void init() throws Error {
+ // http://www.regular-expressions.info/email.html
+ // matches john dep aol museum not john aol com
+ email_regex = new Regex("[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\\.)+[A-Z]{2,5}", RegexCompileFlags.CASELESS);
+}
+
+internal void terminate() {
+ email_regex = null;
+}
+
/**
* Basic validation of a string intended to be parsed as an absolute URI.
*
@@ -57,5 +69,12 @@ public Soup.URI parse(string uri) throws Error {
return parsed;
}
+/**
+ * Validates a string as a valid RFC822 mailbox (i.e. email) address.
+ */
+public bool is_valid_mailbox(string str) {
+ return email_regex.match(str);
+}
+
}
diff --git a/src/util/util.vala b/src/util/util.vala
index 8bc0b78..66337b3 100644
--- a/src/util/util.vala
+++ b/src/util/util.vala
@@ -14,12 +14,14 @@ public void init() throws Error {
// internal init
Markup.init();
+ URI.init();
}
public void terminate() {
if (!Unit.do_terminate(ref init_count))
return;
+ URI.terminate();
Markup.terminate();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]