summaryrefslogtreecommitdiff
path: root/users/app
diff options
context:
space:
mode:
Diffstat (limited to 'users/app')
-rw-r--r--users/app/assets/javascripts/users.js.coffee4
-rw-r--r--users/app/controllers/email_aliases_controller.rb39
-rw-r--r--users/app/controllers/users_controller.rb5
-rw-r--r--users/app/helpers/email_aliases_helper.rb11
-rw-r--r--users/app/models/email.rb17
-rw-r--r--users/app/models/local_email.rb15
-rw-r--r--users/app/models/user.rb73
-rw-r--r--users/app/views/emails/_email.html.haml4
-rw-r--r--users/app/views/users/_email_aliases.html.haml6
-rw-r--r--users/app/views/users/edit.html.haml1
10 files changed, 172 insertions, 3 deletions
diff --git a/users/app/assets/javascripts/users.js.coffee b/users/app/assets/javascripts/users.js.coffee
index 0595292..0c1fb55 100644
--- a/users/app/assets/javascripts/users.js.coffee
+++ b/users/app/assets/javascripts/users.js.coffee
@@ -32,3 +32,7 @@ $(document).ready ->
$('.user.form.change_password').submit srp.update
$('.user.form.change_password').submit preventDefault
$('.user.typeahead').typeahead({source: pollUsers});
+ $('a[data-toggle="tab"]').on('shown', ->
+ $(ClientSideValidations.selectors.forms).validate()
+ )
+
diff --git a/users/app/controllers/email_aliases_controller.rb b/users/app/controllers/email_aliases_controller.rb
new file mode 100644
index 0000000..751df85
--- /dev/null
+++ b/users/app/controllers/email_aliases_controller.rb
@@ -0,0 +1,39 @@
+class EmailAliasesController < ApplicationController
+
+ before_filter :fetch_user
+
+ respond_to :html
+
+ # get a list of email aliases for the given user?
+ def index
+ @aliases = @user.email_aliases
+ respond_with @aliases
+ end
+
+ def create
+ @alias = @user.add_email_alias(params[:email_alias])
+ flash[:notice] = t(:email_alias_created_successfully) unless @alias.errors
+ respond_with @alias, :location => edit_user_path(@user, :anchor => :email)
+ end
+
+ def update
+ @alias = @user.get_email_alias(params[:id])
+ @alias.set_email(params[:email_alias])
+ flash[:notice] = t(:email_alias_updated_successfully) unless @alias.errors
+ respond_with @alias, :location => edit_user_path(@user, :anchor => :email)
+ end
+
+ def destroy
+ @alias = @user.get_email_alias(params[:id])
+ flash[:notice] = t(:email_alias_destroyed_successfully)
+ @alias.destroy
+ redirect_to edit_user_path(@user, :anchor => :email)
+ end
+
+ protected
+
+ def fetch_user
+ @user = User.find_by_param(params[:user_id])
+ access_denied unless admin? or (@user == current_user)
+ end
+end
diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb
index 4921a4a..811e8e5 100644
--- a/users/app/controllers/users_controller.rb
+++ b/users/app/controllers/users_controller.rb
@@ -30,8 +30,11 @@ class UsersController < ApplicationController
end
def update
- if @user.update_attributes(params[:user])
+ @user.attributes = params[:user]
+ if @user.changed? and @user.save
flash[:notice] = t(:user_updated_successfully)
+ else
+ flash[:error] = @user.errors.full_messages
end
respond_with @user, :location => edit_user_path(@user)
end
diff --git a/users/app/helpers/email_aliases_helper.rb b/users/app/helpers/email_aliases_helper.rb
new file mode 100644
index 0000000..b56b068
--- /dev/null
+++ b/users/app/helpers/email_aliases_helper.rb
@@ -0,0 +1,11 @@
+module EmailAliasesHelper
+
+ def email_alias_form(options = {})
+ simple_form_for [@user, EmailAlias.new()],
+ :html => {:class => "form-horizontal email-alias form"},
+ :validate => true do |f|
+ yield f
+ end
+ end
+
+end
diff --git a/users/app/models/email.rb b/users/app/models/email.rb
new file mode 100644
index 0000000..4b01838
--- /dev/null
+++ b/users/app/models/email.rb
@@ -0,0 +1,17 @@
+class Email
+ include CouchRest::Model::Embeddable
+
+ property :email, String
+
+ validates :email,
+ :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, :message => "needs to be a valid email address"}
+
+ def initialize(attributes = nil, &block)
+ attributes = {:email => attributes} if attributes.is_a? String
+ super(attributes, &block)
+ end
+
+ def to_s
+ email
+ end
+end
diff --git a/users/app/models/local_email.rb b/users/app/models/local_email.rb
new file mode 100644
index 0000000..7cca4f4
--- /dev/null
+++ b/users/app/models/local_email.rb
@@ -0,0 +1,15 @@
+class LocalEmail < Email
+
+ validate :unique_on_server
+
+ def to_partial_path
+ "emails/email"
+ end
+
+ def unique_on_server
+ has_email = User.find_by_email_or_alias(email)
+ if has_email && has_email != self.base_doc
+ errors.add(:email, "has already been taken")
+ end
+ end
+end
diff --git a/users/app/models/user.rb b/users/app/models/user.rb
index 340ad9c..10f358d 100644
--- a/users/app/models/user.rb
+++ b/users/app/models/user.rb
@@ -3,11 +3,13 @@ class User < CouchRest::Model::Base
use_database :users
property :login, String, :accessible => true
- property :email, String, :accessible => true
- property :email_forward, String, :accessible => true
property :password_verifier, String, :accessible => true
property :password_salt, String, :accessible => true
+ property :email, String, :accessible => true
+ property :email_forward, String, :accessible => true
+ property :email_aliases, [LocalEmail]
+
validates :login, :password_salt, :password_verifier,
:presence => true
@@ -26,11 +28,48 @@ class User < CouchRest::Model::Base
:confirmation => true,
:format => { :with => /.{8}.*/, :message => "needs to be at least 8 characters long" }
+ # TODO: write a proper email validator to be used in the different places
+ validates :email,
+ :format => { :with => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/, :message => "needs to be a valid email address"}
+
+ validates :email_forward,
+ :format => { :with => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/, :message => "needs to be a valid email address"}
+
+ validate :no_duplicate_email_aliases
+
+ validate :email_aliases_differ_from_email
+
timestamps!
design do
view :by_login
view :by_created_at
+ view :by_email
+ view :by_email_alias,
+ :map => <<-EOJS
+ function(doc) {
+ if (doc.type != 'User') {
+ return;
+ }
+ doc.email_aliases.forEach(function(alias){
+ emit(alias.email, doc);
+ });
+ }
+ EOJS
+ view :by_email_or_alias,
+ :map => <<-EOJS
+ function(doc) {
+ if (doc.type != 'User') {
+ return;
+ }
+ if (doc.email) {
+ emit(doc.email, doc);
+ }
+ doc.email_aliases.forEach(function(alias){
+ emit(alias.email, doc);
+ });
+ }
+ EOJS
end
class << self
@@ -75,6 +114,36 @@ class User < CouchRest::Model::Base
APP_CONFIG['admins'].include? self.login
end
+ def add_email_alias(email)
+ email = LocalEmail.new(email) unless email.is_a? Email
+ email_aliases << email
+ end
+
+ # this currently only adds the first email address submitted.
+ # All the ui needs for now.
+ def email_aliases_attributes=(attrs)
+ if attrs && attrs.values.first
+ add_email_alias attrs.values.first
+ end
+ end
+
+ ##
+ # Validation Functions
+ ##
+
+ # TODO: How do we handle these errors?
+ def no_duplicate_email_aliases
+ if email_aliases.count != email_aliases.map(&:email).uniq.count
+ errors.add(:email_aliases, "include a duplicate")
+ end
+ end
+
+ def email_aliases_differ_from_email
+ if email_aliases.map(&:email).include?(email)
+ errors.add(:email_aliases, "include the original email address")
+ end
+ end
+
protected
def password
password_verifier
diff --git a/users/app/views/emails/_email.html.haml b/users/app/views/emails/_email.html.haml
new file mode 100644
index 0000000..f182ed9
--- /dev/null
+++ b/users/app/views/emails/_email.html.haml
@@ -0,0 +1,4 @@
+%li.pull-right
+ %code= email
+ %i.icon-remove
+.clearfix
diff --git a/users/app/views/users/_email_aliases.html.haml b/users/app/views/users/_email_aliases.html.haml
new file mode 100644
index 0000000..646480e
--- /dev/null
+++ b/users/app/views/users/_email_aliases.html.haml
@@ -0,0 +1,6 @@
+.span6
+ %ul.unstyled
+ =render @user.email_aliases
+.clearfix
+= f.simple_fields_for :email_aliases, Email.new do |e|
+ = e.input :email, :placeholder => "alias@#{request.domain}"
diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml
index b33c19b..92ab71b 100644
--- a/users/app/views/users/edit.html.haml
+++ b/users/app/views/users/edit.html.haml
@@ -14,3 +14,4 @@
.tab-pane#email
= user_form_with 'email_field', :legend => :set_email_address
= user_form_with 'email_forward_field', :legend => :forward_email
+ = user_form_with 'email_aliases', :legend => :add_email_alias