summaryrefslogtreecommitdiff
path: root/users/app
diff options
context:
space:
mode:
authorjessib <jessib@leap.se>2013-07-08 11:30:35 -0700
committerjessib <jessib@leap.se>2013-07-08 11:30:35 -0700
commitfc3c5994df61de04b8b17b495a638efc0d760126 (patch)
tree644aa93dfd0a6da2ed9b20ba688712fb9082f425 /users/app
parentcfb9e1d4c2e954222b77c4dd11e06ae3a0092be5 (diff)
parent3113f8b814417a896ad5340fda88927733f8ab22 (diff)
Merge branch 'master' into feature/disable_account
Conflicts: users/app/controllers/users_controller.rb users/app/helpers/users_helper.rb users/app/views/users/edit.html.haml users/app/views/users/show.html.haml users/config/locales/en.yml
Diffstat (limited to 'users/app')
m---------users/app/assets/javascripts/srp0
-rw-r--r--users/app/assets/javascripts/users.js74
-rw-r--r--users/app/assets/javascripts/users.js.coffee46
-rw-r--r--users/app/controllers/account_settings_controller.rb0
-rw-r--r--users/app/controllers/controller_extension/authentication.rb15
-rw-r--r--users/app/controllers/email_aliases_controller.rb18
-rw-r--r--users/app/controllers/email_settings_controller.rb41
-rw-r--r--users/app/controllers/overviews_controller.rb9
-rw-r--r--users/app/controllers/sessions_controller.rb11
-rw-r--r--users/app/controllers/users_base_controller.rb18
-rw-r--r--users/app/controllers/users_controller.rb64
-rw-r--r--users/app/controllers/v1/users_controller.rb20
-rw-r--r--users/app/helpers/users_helper.rb37
-rw-r--r--users/app/models/user.rb1
-rw-r--r--users/app/views/email_settings/edit.html.haml38
-rw-r--r--users/app/views/emails/_email.html.haml2
-rw-r--r--users/app/views/overviews/show.html.haml18
-rw-r--r--users/app/views/sessions/_admin_nav.html.haml6
-rw-r--r--users/app/views/sessions/_nav.html.haml13
-rw-r--r--users/app/views/sessions/new.html.haml13
-rw-r--r--users/app/views/users/_cancel_account.html.haml9
-rw-r--r--users/app/views/users/_edit.html.haml42
-rw-r--r--users/app/views/users/_email_aliases.html.haml6
-rw-r--r--users/app/views/users/_email_field.html.haml1
-rw-r--r--users/app/views/users/_email_forward_field.html.haml1
-rw-r--r--users/app/views/users/_form.html.haml11
-rw-r--r--users/app/views/users/_legend_and_submit.html.haml4
-rw-r--r--users/app/views/users/_login_and_password_fields.html.haml2
-rw-r--r--users/app/views/users/_login_field.html.haml1
-rw-r--r--users/app/views/users/_password_fields.html.haml2
-rw-r--r--users/app/views/users/_public_key_field.html.haml1
-rw-r--r--users/app/views/users/_user.html.haml12
-rw-r--r--users/app/views/users/edit.html.haml20
-rw-r--r--users/app/views/users/index.html.haml30
-rw-r--r--users/app/views/users/new.html.haml23
-rw-r--r--users/app/views/users/show.html.haml32
36 files changed, 344 insertions, 297 deletions
diff --git a/users/app/assets/javascripts/srp b/users/app/assets/javascripts/srp
-Subproject e7a0b830b8f994316a560001a9e7397422b184b
+Subproject 926a5d5960db51903e33c8496487da59f9f4124
diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js
new file mode 100644
index 0000000..1d05692
--- /dev/null
+++ b/users/app/assets/javascripts/users.js
@@ -0,0 +1,74 @@
+(function() {
+ //
+ // LOCAL FUNCTIONS
+ //
+
+ var poll_users, prevent_default, form_failed, form_passed;
+
+ prevent_default = function(event) {
+ return event.preventDefault();
+ };
+
+ poll_users = function(query, process) {
+ return $.get("/1/users.json", {
+ query: query
+ }).done(process);
+ };
+
+ //
+ // PUBLIC FUNCTIONS
+ //
+
+ srp.session = new srp.Session();
+
+ srp.signedUp = function() {
+ return srp.login();
+ };
+
+ srp.loggedIn = function() {
+ return window.location = '/';
+ };
+
+ srp.updated = function() {
+ return window.location = '/users/' + srp.session.id();
+ };
+
+ //
+ // if a json request returns an error, this function gets called and
+ // decorates the appropriate fields with the error messages.
+ //
+ srp.error = function(message) {
+ var element, error, field;
+ if ($.isPlainObject(message) && message.errors) {
+ for (field in message.errors) {
+ error = message.errors[field];
+ element = $('form input[name$="[' + field + ']"]');
+ if (!element) {
+ next;
+ }
+ element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false);
+ }
+ } else if (message.error) {
+ alert_message(message.error);
+ } else {
+ alert_message(JSON.stringify(message));
+ }
+ };
+
+ //
+ // INIT
+ //
+
+ $(document).ready(function() {
+ $('#new_user').submit(prevent_default);
+ $('#new_user').submit(srp.signup);
+ $('#new_session').submit(prevent_default);
+ $('#new_session').submit(srp.login);
+ $('#update_login_and_password').submit(prevent_default);
+ $('#update_login_and_password').submit(srp.update);
+ return $('#user-typeahead').typeahead({
+ source: poll_users
+ });
+ });
+
+}).call(this);
diff --git a/users/app/assets/javascripts/users.js.coffee b/users/app/assets/javascripts/users.js.coffee
deleted file mode 100644
index 955556c..0000000
--- a/users/app/assets/javascripts/users.js.coffee
+++ /dev/null
@@ -1,46 +0,0 @@
-preventDefault = (event) ->
- event.preventDefault()
-
-srp.session = new srp.Session()
-srp.signedUp = ->
- srp.login()
-
-srp.loggedIn = ->
- window.location = '/'
-
-#// TODO: not sure this is what we want.
-srp.updated = ->
- window.location = '/'
-
-srp.error = (message) ->
- if $.isPlainObject(message) && message.errors
- for field, error of message.errors
- element = $('form input[name$="['+field+']"]')
- next unless element
- element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false)
- else
- alert(message)
-
-pollUsers = (query, process) ->
- $.get( "/users.json", query: query).done(process)
-
-followLocationHash = ->
- location = window.location.hash
- if location
- href_select = 'a[href="' + location + '"]'
- link = $(href_select)
- link.tab('show') if link
-
-$(document).ready ->
- followLocationHash()
- $('#new_user').submit preventDefault
- $('#new_user').submit srp.signup
- $('#new_session').submit preventDefault
- $('#new_session').submit srp.login
- $('.user.form.update_login_and_password').submit srp.update
- $('.user.form.update_login_and_password').submit preventDefault
- $('.user.typeahead').typeahead({source: pollUsers});
- $('a[data-toggle="tab"]').on('shown', ->
- $(ClientSideValidations.selectors.forms).validate()
- )
-
diff --git a/users/app/controllers/account_settings_controller.rb b/users/app/controllers/account_settings_controller.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/users/app/controllers/account_settings_controller.rb
diff --git a/users/app/controllers/controller_extension/authentication.rb b/users/app/controllers/controller_extension/authentication.rb
index f0a6564..72df7a7 100644
--- a/users/app/controllers/controller_extension/authentication.rb
+++ b/users/app/controllers/controller_extension/authentication.rb
@@ -38,9 +38,18 @@ module ControllerExtension::Authentication
end
def access_denied
- # TODO: should we redirect to the root_url in either case, and have the root_url include the login screen (and also ability to create unauthenticated tickets) when no user is logged in?
- redirect_to login_url, :alert => "Not authorized" if !logged_in?
- redirect_to root_url, :alert => "Not authorized" if logged_in?
+ respond_to do |format|
+ format.html do
+ if logged_in?
+ redirect_to root_url, :alert => t(:not_authorized)
+ else
+ redirect_to login_url, :alert => t(:not_authorized_login)
+ end
+ end
+ format.json do
+ render :json => {'error' => t(:not_authorized)}, status: :unprocessable_entity
+ end
+ end
end
def admin?
diff --git a/users/app/controllers/email_aliases_controller.rb b/users/app/controllers/email_aliases_controller.rb
index 3b0d5ac..4628a7f 100644
--- a/users/app/controllers/email_aliases_controller.rb
+++ b/users/app/controllers/email_aliases_controller.rb
@@ -1,20 +1,12 @@
-class EmailAliasesController < ApplicationController
-
+class EmailAliasesController < UsersBaseController
before_filter :fetch_user
- respond_to :html
-
def destroy
@alias = @user.email_aliases.delete(params[:id])
- @user.save
- flash[:notice] = t(:email_alias_destroyed_successfully, :alias => @alias)
- redirect_to edit_user_path(@user, :anchor => :email)
+ if @user.save
+ flash[:notice] = t(:email_alias_destroyed_successfully, :alias => bold(@alias))
+ end
+ redirect_to edit_user_email_settings_path(@user)
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/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb
new file mode 100644
index 0000000..f7d85be
--- /dev/null
+++ b/users/app/controllers/email_settings_controller.rb
@@ -0,0 +1,41 @@
+class EmailSettingsController < UsersBaseController
+
+ before_filter :authorize
+ before_filter :fetch_user
+
+ def edit
+ @email_alias = LocalEmail.new
+ end
+
+ def update
+ @user.attributes = cleanup_params(params[:user])
+ if @user.changed?
+ if @user.save
+ flash[:notice] = t(:changes_saved)
+ redirect
+ else
+ if @user.email_aliases.last && !@user.email_aliases.last.valid?
+ # display bad alias in text field:
+ @email_alias = @user.email_aliases.pop
+ end
+ render 'email_settings/edit'
+ end
+ else
+ redirect
+ end
+ end
+
+ private
+
+ def redirect
+ redirect_to edit_user_email_settings_url(@user)
+ end
+
+ def cleanup_params(user)
+ if !user['email_forward'].nil? && user['email_forward'].empty?
+ user.delete('email_forward') # don't allow "" as an email forward
+ end
+ user
+ end
+
+end
diff --git a/users/app/controllers/overviews_controller.rb b/users/app/controllers/overviews_controller.rb
new file mode 100644
index 0000000..52ce267
--- /dev/null
+++ b/users/app/controllers/overviews_controller.rb
@@ -0,0 +1,9 @@
+class OverviewsController < UsersBaseController
+
+ before_filter :authorize
+ before_filter :fetch_user
+
+ def show
+ end
+
+end
diff --git a/users/app/controllers/sessions_controller.rb b/users/app/controllers/sessions_controller.rb
index 01ecff6..d6c455b 100644
--- a/users/app/controllers/sessions_controller.rb
+++ b/users/app/controllers/sessions_controller.rb
@@ -22,4 +22,15 @@ class SessionsController < ApplicationController
logout
redirect_to root_path
end
+
+ #
+ # this is a bad hack, but user_overview_url(user) is not available
+ # also, this doesn't work because the redirect happens as a PUT. no idea why.
+ #
+ #Warden::Manager.after_authentication do |user, auth, opts|
+ # response = Rack::Response.new
+ # response.redirect "/users/#{user.id}/overview"
+ # throw :warden, response.finish
+ #end
+
end
diff --git a/users/app/controllers/users_base_controller.rb b/users/app/controllers/users_base_controller.rb
new file mode 100644
index 0000000..dc2fa16
--- /dev/null
+++ b/users/app/controllers/users_base_controller.rb
@@ -0,0 +1,18 @@
+#
+# common base class for all user related controllers
+#
+
+class UsersBaseController < ApplicationController
+
+ protected
+
+ def fetch_user
+ @user = User.find_by_param(params[:user_id] || params[:id])
+ if !@user && admin?
+ redirect_to users_url, :alert => t(:no_such_thing, :thing => 'user')
+ elsif !admin? && @user != current_user
+ access_denied
+ end
+ end
+
+end
diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb
index 189e7d4..f66277d 100644
--- a/users/app/controllers/users_controller.rb
+++ b/users/app/controllers/users_controller.rb
@@ -1,44 +1,37 @@
-class UsersController < ApplicationController
+#
+# This is an HTML-only controller. For the JSON-only controller, see v1/users_controller.rb
+#
- before_filter :authorize, :only => [:show, :edit, :destroy, :update]
+class UsersController < UsersBaseController
+
+ before_filter :authorize, :only => [:show, :edit, :update, :destroy]
before_filter :fetch_user, :only => [:show, :edit, :update, :destroy, :deactivate, :enable]
- before_filter :authorize_self, :only => [:update]
- before_filter :set_anchor, :only => [:edit, :update]
before_filter :authorize_admin, :only => [:index, :deactivate, :enable]
- respond_to :json, :html
+ respond_to :html
def index
if params[:query]
- @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ)
+ if @user = User.find_by_login(params[:query])
+ redirect_to user_overview_url(@user)
+ return
+ else
+ @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ)
+ end
else
@users = User.by_created_at.descending
end
- @users = @users.limit(10)
- respond_with @users.map(&:login).sort
+ @users = @users.limit(100)
end
def new
@user = User.new
end
- def create
- @user = User.create(params[:user])
- respond_with @user
+ def show
end
def edit
- @email_alias = LocalEmail.new
- end
-
- def update
- @user.attributes = params[:user]
- if @user.changed? and @user.save
- flash[:notice] = t(:user_updated_successfully)
- elsif @user.email_aliases.last and !@user.email_aliases.last.valid?
- @email_alias = @user.email_aliases.pop
- end
- respond_with @user, :location => edit_user_path(@user, :anchor => @anchor)
end
def deactivate
@@ -55,32 +48,7 @@ class UsersController < ApplicationController
def destroy
@user.destroy
- redirect_to admin? ? users_path : root_path
- end
-
- protected
-
- def fetch_user
- # authorize filter has been checked first, so won't get here unless authenticated
- @user = User.find_by_param(params[:id])
- if !@user and admin?
- redirect_to users_path, :alert => t(:no_such_thing, :thing => 'user')
- return
- end
- access_denied unless admin? or (@user == current_user)
- end
-
- def authorize_self
- # have already checked that authorized
- access_denied unless (@user == current_user)
+ redirect_to admin? ? users_url : root_url
end
- def set_anchor
- @anchor = email_settings? ? :email : :account
- end
-
- def email_settings?
- params[:user] &&
- params[:user].keys.detect{|key| key.index('email')}
- end
end
diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb
index 617bd4b..fda56f2 100644
--- a/users/app/controllers/v1/users_controller.rb
+++ b/users/app/controllers/v1/users_controller.rb
@@ -1,20 +1,32 @@
module V1
- class UsersController < ApplicationController
+ class UsersController < UsersBaseController
skip_before_filter :verify_authenticity_token
+ before_filter :fetch_user, :only => [:update]
before_filter :authorize, :only => [:update]
+ before_filter :authorize_admin, :only => [:index]
respond_to :json
+ def index
+ if params[:query]
+ @users = User.by_login.startkey(params[:query]).endkey(params[:query].succ)
+ respond_with @users.map(&:login).sort
+ else
+ render :json => {'error' => 'query required', 'status' => :unprocessable_entity}
+ end
+ end
+
def create
@user = User.create(params[:user])
respond_with @user # return ID instead?
end
def update
- # For now, only allow public key to be updated via the API. Eventually we might want to store in a config what attributes can be updated via the API.
- @user = User.find_by_param(params[:id])
- @user.update_attributes params[:user].slice(:public_key) if params[:user].respond_to?(:slice)
+ @user.update_attributes params[:user]
+ if @user.valid?
+ flash[:notice] = t(:user_updated_successfully)
+ end
respond_with @user
end
diff --git a/users/app/helpers/users_helper.rb b/users/app/helpers/users_helper.rb
index f731aab..f56faab 100644
--- a/users/app/helpers/users_helper.rb
+++ b/users/app/helpers/users_helper.rb
@@ -1,40 +1,7 @@
module UsersHelper
- def user_form_with(partial, options = {})
- user_form(options) do |f|
- options[:f] = f
- render :partial => partial,
- :layout => 'legend_and_submit',
- :locals => options
- end
- end
-
- def user_form(options = {})
- simple_form_for @user,
- :html => user_form_html_options(options),
- :validate => true do |f|
- yield f
- end
- end
-
- def user_form_html_options(options)
- { :class => user_form_html_classes(options).join(" "),
- :id => dom_id(@user, options[:legend])
- }
- end
-
- def user_form_html_classes(options)
- classes = %W/form-horizontal user form/
- classes << options[:legend]
- classes << (@user.new_record? ? 'new' : 'edit')
- classes.compact
- end
-
- def user_field(field)
- value = @user.send(field)
- value = value.to_s(:long) if field.end_with? '_at'
- value = 'not set' if value.nil?
- value
+ def user_form_class(*classes)
+ (classes + ['user', 'form', (@user.new_record? ? 'new' : 'edit')]).compact.join(' ')
end
def wrapped(item, options = {})
diff --git a/users/app/models/user.rb b/users/app/models/user.rb
index 0cf37cf..413b4ac 100644
--- a/users/app/models/user.rb
+++ b/users/app/models/user.rb
@@ -44,6 +44,7 @@ class User < CouchRest::Model::Base
:format => { :with => /.{8}.*/, :message => "needs to be at least 8 characters long" }
validates :email_forward,
+ :allow_blank => true,
:format => { :with => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/, :message => "needs to be a valid email address"}
timestamps!
diff --git a/users/app/views/email_settings/edit.html.haml b/users/app/views/email_settings/edit.html.haml
new file mode 100644
index 0000000..7757a31
--- /dev/null
+++ b/users/app/views/email_settings/edit.html.haml
@@ -0,0 +1,38 @@
+- form_options = {:url => user_email_settings_path(@user), :html => {:class => 'form-horizontal'}, :validate => true}
+- alias_error_class = @email_alias.username && !@email_alias.valid? ? 'error' : ''
+
+- content_for :head do
+ :css
+ table.aliases tr:first-child td {
+ border-top: none;
+ }
+
+= simple_form_for @user, form_options.dup do |f|
+ %legend= t(:email_aliases)
+ .control-group
+ %label.control-label= t(:current_aliases)
+ .controls
+ %table.table.table-condensed.no-header.slim.aliases
+ - if @user.email_aliases.any?
+ - @user.email_aliases.each do |email|
+ %tr
+ %td= email
+ %td= link_to(icon(:remove) + t(:remove), user_email_alias_path(@user, email), :method => :delete)
+ - else
+ %tr
+ %td{:colspan=>2}= t(:none)
+ .control-group{:class => alias_error_class}
+ %label.control-label= t(:add_email_alias)
+ .controls
+ = f.simple_fields_for :email_aliases, @email_alias do |e|
+ .input-append
+ = e.input_field :username
+ = e.submit t(:add), :class => 'btn'
+ = e.error :username
+
+= simple_form_for @user, form_options do |f|
+ %legend= t(:advanced_options)
+ = f.input :email_forward
+ = f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "full-width", :rows => 4}
+ .form-actions
+ = f.submit t(:save), :class => 'btn btn-primary'
diff --git a/users/app/views/emails/_email.html.haml b/users/app/views/emails/_email.html.haml
index c81b396..ea59cec 100644
--- a/users/app/views/emails/_email.html.haml
+++ b/users/app/views/emails/_email.html.haml
@@ -3,4 +3,4 @@
- if local_assigns[:with].try(:include?, :delete)
= link_to(user_email_alias_path(@user, email), :method => :delete) do
%i.icon-remove
-.clearfix
+
diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml
new file mode 100644
index 0000000..b8ad814
--- /dev/null
+++ b/users/app/views/overviews/show.html.haml
@@ -0,0 +1,18 @@
+.overview
+
+ %h2.first= t(:overview_welcome, :username => @user.login)
+
+ - if admin?
+ %p
+ = t(:created)
+ = @user.created_at
+ %br
+ = t(:updated)
+ = @user.updated_at
+
+ %p= t(:overview_intro)
+
+ %ul.unstyled
+ %li= icon('user') + link_to(t(:overview_account), edit_user_path(@user))
+ %li= icon('envelope') + link_to(t(:overview_email), edit_user_email_settings_path(@user))
+ %li= icon('question-sign') + link_to(t(:overview_tickets), user_tickets_path(@user))
diff --git a/users/app/views/sessions/_admin_nav.html.haml b/users/app/views/sessions/_admin_nav.html.haml
deleted file mode 100644
index 14dfbdc..0000000
--- a/users/app/views/sessions/_admin_nav.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-%a#admin-menu{"data-toggle" => "dropdown", :role => :button}
- Admin
-%ul.dropdown-menu{:role => "menu", "aria-labelledby" => "admin-menu"}
- %li
- = link_to Ticket.model_name.human(:count => ""), tickets_path, {:tabindex => -1}
- = link_to User.model_name.human(:count => ""), users_path, {:tabindex => -1}
diff --git a/users/app/views/sessions/_nav.html.haml b/users/app/views/sessions/_nav.html.haml
deleted file mode 100644
index ac85bb5..0000000
--- a/users/app/views/sessions/_nav.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-- if logged_in?
- - if admin?
- %li.dropdown
- = render 'sessions/admin_nav'
- %li
- = link_to current_user.login, edit_user_path(current_user)
- %li
- = link_to t(:logout), logout_path, :method => :delete
-- else
- %li
- = link_to t(:login), login_path
- %li
- = link_to t(:signup), signup_path
diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml
index 6743407..c915968 100644
--- a/users/app/views/sessions/new.html.haml
+++ b/users/app/views/sessions/new.html.haml
@@ -1,9 +1,10 @@
-.span8.offset2
+.span1
+.span9
= render :partial => 'users/warnings'
%h2=t :login
= simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f|
- %legend=t :login_message
- = f.input :login, :input_html => { :id => :srp_username }
- = f.input :password, :required => true, :input_html => { :id => :srp_password }
- = f.button :submit, :value => t(:login), :class => 'btn-primary'
- = link_to t(:cancel), root_url, :class => :btn \ No newline at end of file
+ = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username }
+ = f.input :password, :required => false, :input_html => { :id => :srp_password }
+ .form-actions
+ = f.button :submit, :value => t(:login), :class => 'btn-primary'
+ = link_to t(:cancel), root_path, :class => 'btn'
diff --git a/users/app/views/users/_cancel_account.html.haml b/users/app/views/users/_cancel_account.html.haml
deleted file mode 100644
index c5ab36a..0000000
--- a/users/app/views/users/_cancel_account.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-%legend
- - if @user == current_user
- =t :cancel_account
- %small You will not be able to login anymore.
- - else
- =t :admin_cancel_account, :username => @user.login
-= link_to user_path(@user), :method => :delete, :confirm => t(:confirm_question), :class => "btn btn-danger" do
- %i.icon-remove.icon-white
- =t :remove_account
diff --git a/users/app/views/users/_edit.html.haml b/users/app/views/users/_edit.html.haml
new file mode 100644
index 0000000..41a68fd
--- /dev/null
+++ b/users/app/views/users/_edit.html.haml
@@ -0,0 +1,42 @@
+-#
+-# edit user form, used by both show and edit actions.
+-#
+
+-#
+-# CHANGE PASSWORD
+-#
+-# * everything about this form is handled with javascript. So take care when changing any ids.
+-# * the login is required when changing the password because it is used as part of the salt when calculating the password verifier.
+-# however, we don't want the user to change their login without generating a new key, so we hide the ui for this
+-# (although it works perfectly fine to change username if the field was visible).
+-#
+- form_options = {:url => '/not-used', :html => {:class => user_form_class('form-horizontal'), :id => 'update_login_and_password'}, :validate => true}
+= simple_form_for @user, form_options do |f|
+ %legend= t(:change_password)
+ = hidden_field_tag 'user_param', @user.to_param
+ .hidden
+ = f.input :login, :label => t(:username), :required => false, :input_html => {:id => :srp_username}
+ = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password }
+ = f.input :password_confirmation, :required => false, :input_html => { :id => :srp_password_confirmation }
+ .control-group
+ .controls
+ = f.submit t(:save), :class => 'btn btn-primary'
+
+-#
+-# DESTROY ACCOUNT
+-#
+
+%legend
+ - if @user == current_user
+ = t(:destroy_my_account)
+ - else
+ = t(:admin_destroy_account, :username => @user.login)
+%p= t(:destroy_account_info)
+= link_to user_path(@user), :method => :delete, :confirm => t(:are_you_sure), :class => "btn btn-danger" do
+ %i.icon-remove.icon-white
+ = t(:destroy_my_account)
+
+- # TODO: should show enabled field if admin is viewing another account.
+- # TODO: admins should be able to deactivate/enable regular accounts, as appropriate. before had:
+- # = render 'deactivate_account' if @user != current_user and @user.enabled?
+- # = render 'enable_account' if @user != current_user and !@user.enabled? \ No newline at end of file
diff --git a/users/app/views/users/_email_aliases.html.haml b/users/app/views/users/_email_aliases.html.haml
deleted file mode 100644
index 6e32700..0000000
--- a/users/app/views/users/_email_aliases.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-.span6
- %ul.unstyled
- = render @user.email_aliases, :as => :li, :with => [:delete]
-.clearfix
-= f.simple_fields_for :email_aliases, @email_alias do |e|
- = e.input :username, :placeholder => "alias"
diff --git a/users/app/views/users/_email_field.html.haml b/users/app/views/users/_email_field.html.haml
deleted file mode 100644
index edf62c9..0000000
--- a/users/app/views/users/_email_field.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= f.input :email, :placeholder => "me@#{APP_CONFIG[:domain]}"
diff --git a/users/app/views/users/_email_forward_field.html.haml b/users/app/views/users/_email_forward_field.html.haml
deleted file mode 100644
index 049428f..0000000
--- a/users/app/views/users/_email_forward_field.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= f.input :email_forward
diff --git a/users/app/views/users/_form.html.haml b/users/app/views/users/_form.html.haml
deleted file mode 100644
index cb51175..0000000
--- a/users/app/views/users/_form.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-- only = local_assigns[:only]
-- html = {:class => 'form-horizontal user form ' + (@user.new_record? ? 'new' : 'edit')}
-= simple_form_for @user, :validate => true, :format => :json, :html => html do |f|
- %legend
- = t(only || :signup_message)
- = yield
- .pull-right
- = f.button :submit
- - unless only
- = link_to t(:cancel), root_url, :class => :btn
- .clearfix
diff --git a/users/app/views/users/_legend_and_submit.html.haml b/users/app/views/users/_legend_and_submit.html.haml
deleted file mode 100644
index 6fc0e4a..0000000
--- a/users/app/views/users/_legend_and_submit.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-%legend= t(legend)
-=yield
-.pull-right= f.button :submit, :value => t(legend)
-.clearfix
diff --git a/users/app/views/users/_login_and_password_fields.html.haml b/users/app/views/users/_login_and_password_fields.html.haml
deleted file mode 100644
index 0baefc7..0000000
--- a/users/app/views/users/_login_and_password_fields.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-= render :partial => 'login_field', :locals => {:f => f}
-= render :partial => 'password_fields', :locals => {:f => f, :password_confirmation_hint => t(:can_retype_old_password)} \ No newline at end of file
diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml
deleted file mode 100644
index 8ab36c3..0000000
--- a/users/app/views/users/_login_field.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= f.input :login, :input_html => { :id => :srp_username }
diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml
deleted file mode 100644
index 47b7b07..0000000
--- a/users/app/views/users/_password_fields.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-= f.input :password, :required => true, :validate => true, :input_html => { :id => :srp_password }
-= f.input :password_confirmation, :required => true, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation }
diff --git a/users/app/views/users/_public_key_field.html.haml b/users/app/views/users/_public_key_field.html.haml
deleted file mode 100644
index af88cbd..0000000
--- a/users/app/views/users/_public_key_field.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "span5", :rows => 20} # will want to tweak this to be wide enough (maybe smaller text?)
diff --git a/users/app/views/users/_user.html.haml b/users/app/views/users/_user.html.haml
index ca03d34..990d9cf 100644
--- a/users/app/views/users/_user.html.haml
+++ b/users/app/views/users/_user.html.haml
@@ -1,10 +1,4 @@
%tr
- %td= link_to user.login, user
- %td= time_ago_in_words(user.created_at) + " ago"
- %td
- = link_to edit_user_path(user), :class => "btn btn-mini btn-primary" do
- %i.icon-edit.icon-white
- Edit
- = link_to user_path(user), :method => :delete, :class => "btn btn-danger btn-mini" do
- %i.icon-remove.icon-white
- Remove
+ %td= link_to user.login, user_overview_path(user)
+ %td= l(user.created_at, :format => :short)
+ %td= l(user.updated_at, :format => :short)
diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml
index 49b4f6c..434c025 100644
--- a/users/app/views/users/edit.html.haml
+++ b/users/app/views/users/edit.html.haml
@@ -1,19 +1 @@
-.span8.offset2
- %h2=t :settings
- - tabs = []
- - content_for :account do
- = user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user
- = render 'deactivate_account' if @user != current_user and @user.enabled?
- = render 'enable_account' if @user != current_user and !@user.enabled?
- = render 'cancel_account'
- - tabs << :account
- - if @user == current_user
- - content_for :email do
- %legend=t :email_address
- =t :associated_email
- = render @user.email_address, :as => :span
- = user_form_with 'public_key_field', :legend => :public_key
- = user_form_with 'email_forward_field', :legend => :forward_email
- = user_form_with 'email_aliases', :legend => :add_email_alias
- - tabs << :email
- = render 'tabs/tabs', :tabs => tabs
+= render 'edit'
diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml
index 9e6a179..fc1001e 100644
--- a/users/app/views/users/index.html.haml
+++ b/users/app/views/users/index.html.haml
@@ -1,17 +1,13 @@
-.page-header
- %h1= User.model_name.human(:count =>User.count)
-.row
- .span8
- %h2= params[:query] ? "Users starting with '#{params[:query]}'" : "Last users who signed up"
- %table.table.table-hover
- %tr
- %th Login
- %th Created
- %th Action
- = render @users.all
- .span4
- %h4 Find user
- = form_tag users_path, :method => :get, :class => "form-search" do
- .input-append
- = text_field_tag :query, "", :class => "user typeahead span2 search-query", :autocomplete => :off
- %button.btn{:type => :submit} Search
+- @show_navigation = false
+
+= form_tag users_path, :method => :get, :class => "form-search" do
+ .input-append
+ = text_field_tag :query, params[:query], :id => 'user-typeahead', :class => "search-query", :autocomplete => :off
+ %button.btn{:type => :submit}= t(:search)
+
+%table.table.table-striped
+ %tr
+ %th= t(:username)
+ %th= t(:created)
+ %th= t(:updated)
+ = render @users.all
diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml
index 80482b2..f8d14b5 100644
--- a/users/app/views/users/new.html.haml
+++ b/users/app/views/users/new.html.haml
@@ -1,12 +1,19 @@
-.span8.offset2
+-#
+-# This form is handled entirely by javascript, so take care when changing element ids.
+-#
+
+- form_options = {:url => '/not-used', :html => {:id => 'new_user', :class => user_form_class('form-horizontal')}, :validate => true}
+
+.span1
+.span9
= render :partial => 'warnings'
%h2=t :signup
- = user_form do |f|
+ = simple_form_for(@user, form_options) do |f|
%legend= t(:signup_message)
- = render :partial => 'login_field', :locals => {:f => f}
- = render :partial => 'password_fields', :locals => {:f => f}
- .pull-right
- = f.button :submit, :class => 'btn-primary'
- = link_to t(:cancel), root_url, :class => :btn
- .clearfix
+ = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username }
+ = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password }
+ = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation }
+ .form-actions
+ = f.button :submit, :value => t(:signup), :class => 'btn btn-primary'
+ = link_to t(:cancel), root_url, :class => 'btn'
diff --git a/users/app/views/users/show.html.haml b/users/app/views/users/show.html.haml
index 52a9cf5..434c025 100644
--- a/users/app/views/users/show.html.haml
+++ b/users/app/views/users/show.html.haml
@@ -1,31 +1 @@
-.span8.offset1
- %h2= @user.login
- .small
- = link_to 'edit', edit_user_path(@user)
- %dl.offset1
- - fields = ['login', 'email_address', 'created_at', 'updated_at', 'email_forward', 'enabled']
- - fields.each do |field|
- %dt
- = field.titleize
- %dd
- = user_field(field)
- %dt
- =t :email_aliases
- %dd
- - aliases = @user.email_aliases
- - if aliases.present?
- %ul.pull-left.unstyled
- = render aliases
- - else
- =t :none
- .clearfix
- %dt
- =t :most_recently_updated_tickets
- %dd
- - tix = @user.most_recent_tickets
- - if tix.present?
- %table
- %tbody
- = render @user.most_recent_tickets
- - else
- =t :none \ No newline at end of file
+= render 'edit'