diff options
Diffstat (limited to 'users/app')
-rw-r--r-- | users/app/assets/javascripts/users.js.coffee | 4 | ||||
-rw-r--r-- | users/app/controllers/email_aliases_controller.rb | 39 | ||||
-rw-r--r-- | users/app/controllers/users_controller.rb | 5 | ||||
-rw-r--r-- | users/app/helpers/email_aliases_helper.rb | 11 | ||||
-rw-r--r-- | users/app/models/email.rb | 17 | ||||
-rw-r--r-- | users/app/models/local_email.rb | 15 | ||||
-rw-r--r-- | users/app/models/user.rb | 73 | ||||
-rw-r--r-- | users/app/views/emails/_email.html.haml | 4 | ||||
-rw-r--r-- | users/app/views/users/_email_aliases.html.haml | 6 | ||||
-rw-r--r-- | users/app/views/users/edit.html.haml | 1 |
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 |