From e58fd0550b4a29fac9d52dc8a78d04333ccc8c06 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 17 Jun 2013 01:27:55 -0700 Subject: new ui - initial user changes --- .../app/controllers/account_settings_controller.rb | 0 users/app/controllers/email_settings_controller.rb | 0 users/app/controllers/overviews_controller.rb | 9 ++++++++ users/app/controllers/users_base_controller.rb | 18 ++++++++++++++++ users/app/helpers/users_helper.rb | 2 +- users/app/views/_login_or_signup.html.haml | 25 ++++++++++++++++++++++ users/app/views/emails/edit.html.haml | 5 +++++ users/app/views/overviews/show.html.haml | 15 +++++++++++++ users/app/views/sessions/_new.html.haml | 7 ++++++ users/app/views/sessions/new.html.haml | 2 +- users/app/views/users/_login_field.html.haml | 2 +- users/app/views/users/_new.html.haml | 7 ++++++ users/app/views/users/_password_fields.html.haml | 4 ++-- users/app/views/users/edit.html.haml | 20 +++-------------- users/app/views/users/new.html.haml | 5 ++--- users/config/locales/en.yml | 17 +++++++++------ users/config/routes.rb | 3 +++ 17 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 users/app/controllers/account_settings_controller.rb create mode 100644 users/app/controllers/email_settings_controller.rb create mode 100644 users/app/controllers/overviews_controller.rb create mode 100644 users/app/controllers/users_base_controller.rb create mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/emails/edit.html.haml create mode 100644 users/app/views/overviews/show.html.haml create mode 100644 users/app/views/sessions/_new.html.haml create mode 100644 users/app/views/users/_new.html.haml (limited to 'users') 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 diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb new file mode 100644 index 0000000..e69de29 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/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/helpers/users_helper.rb b/users/app/helpers/users_helper.rb index 9feae62..559b3f7 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -24,7 +24,7 @@ module UsersHelper end def user_form_html_classes(options) - classes = %W/form-horizontal user form/ + classes = %W/user form/ classes << options[:legend] classes << (@user.new_record? ? 'new' : 'edit') classes.compact diff --git a/users/app/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml new file mode 100644 index 0000000..b353526 --- /dev/null +++ b/users/app/views/_login_or_signup.html.haml @@ -0,0 +1,25 @@ +// +// displays a little widget to login or sign up +// + +%ul.nav.nav-tabs + %li.active + %a{:href => ''}= t(:login) + %li + = link_to t(:signup), new_user_path + += render 'sessions/new' + +// +// this is nice, but it doesn't work because both forms have the same names for fields. +// +// %ul.nav.nav-tabs +// %li.active +// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) +// %li +// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) +// .tab-content +// #login.tab-pane.active +// = render 'sessions/new' +// #signup.tab-pane +// = render 'users/new' diff --git a/users/app/views/emails/edit.html.haml b/users/app/views/emails/edit.html.haml new file mode 100644 index 0000000..b44b569 --- /dev/null +++ b/users/app/views/emails/edit.html.haml @@ -0,0 +1,5 @@ + + += 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 diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml new file mode 100644 index 0000000..eda9899 --- /dev/null +++ b/users/app/views/overviews/show.html.haml @@ -0,0 +1,15 @@ +%p + Username: + = @user.login + +%p + User since: + = @user.created_at + +%p + Last update: + = @user.updated_at + +%p + Quota: + N/A \ No newline at end of file diff --git a/users/app/views/sessions/_new.html.haml b/users/app/views/sessions/_new.html.haml new file mode 100644 index 0000000..640fec5 --- /dev/null +++ b/users/app/views/sessions/_new.html.haml @@ -0,0 +1,7 @@ +- @session ||= Session.new += simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| + = 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' + // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 6743407..960919a 100644 --- a/users/app/views/sessions/new.html.haml +++ b/users/app/views/sessions/new.html.haml @@ -6,4 +6,4 @@ = 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 + = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/_login_field.html.haml b/users/app/views/users/_login_field.html.haml index 8ab36c3..e58c36f 100644 --- a/users/app/views/users/_login_field.html.haml +++ b/users/app/views/users/_login_field.html.haml @@ -1 +1 @@ -= f.input :login, :input_html => { :id => :srp_username } += f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } diff --git a/users/app/views/users/_new.html.haml b/users/app/views/users/_new.html.haml new file mode 100644 index 0000000..3d0f2ac --- /dev/null +++ b/users/app/views/users/_new.html.haml @@ -0,0 +1,7 @@ +- @user ||= User.new += user_form do |f| + = render :partial => 'users/login_field', :locals => {:f => f} + = render :partial => 'users/password_fields', :locals => {:f => f} + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' + = link_to t(:cancel), root_url, :class => :btn diff --git a/users/app/views/users/_password_fields.html.haml b/users/app/views/users/_password_fields.html.haml index 47b7b07..7b3358d 100644 --- a/users/app/views/users/_password_fields.html.haml +++ b/users/app/views/users/_password_fields.html.haml @@ -1,2 +1,2 @@ -= 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 } += f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } += f.input :password_confirmation, :required => false, :hint => local_assigns[:password_confirmation_hint], :input_html => { :id => :srp_password_confirmation } diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index 97bd48d..4e70d69 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,17 +1,3 @@ -.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 '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 += user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user += render 'cancel_account' + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index 80482b2..7d29de2 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -5,8 +5,7 @@ %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' + .form-actions + = f.button :submit, :value => t(:signup), :class => 'btn-primary' = link_to t(:cancel), root_url, :class => :btn - .clearfix diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 32d183b..3c42b55 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -1,9 +1,14 @@ en: - none: "None." - signup: "Sign up" + email_settings: "Email Settings" + account_settings: "Account Settings" + logout: "Logout" + none: "None" + signup: "Sign Up" signup_message: "Please create an account." cancel: "Cancel" - login: "Login" + login: "Log In" + username: "Username" + password: "Password" login_message: "Please login with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." @@ -20,7 +25,7 @@ en: user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored PGP key" + use_ascii_key: "Use ASCII-armored OpenPGP key" can_retype_old_password: "Retype your old password if you would like to keep that" associated_email: "The associated email address is" cookie_disabled_warning: "You have cookies disabled. You will not be able to login until you enable cookies." @@ -28,7 +33,7 @@ en: activemodel: models: - user: + user: one: User other: "%{count} Users" simple_form: @@ -42,4 +47,4 @@ en: placeholders: user: email_forward: "my_other_email@domain.net" - + diff --git a/users/config/routes.rb b/users/config/routes.rb index 9a9a40e..d07cda9 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -14,6 +14,9 @@ Rails.application.routes.draw do get "signup" => "users#new", :as => "signup" resources :users do + resource :overview, :only => [:show] + resource :email_settings, :only => [:edit, :update] + resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From 2e4ebdb84a464cf2ee902eb6e9bc955d77bafa73 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 19 Jun 2013 00:37:04 -0700 Subject: add commented out code of how redirect should work with Warden, although I can't get it working. --- users/app/controllers/sessions_controller.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'users') 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 -- cgit v1.2.3 From e996432cbd50f4dadaae0ff62ac3f286ab125b1f Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:11:23 -0700 Subject: add js to report all errors to the user, not just ones related to field validation. --- users/app/assets/javascripts/users.js | 74 ++++++++++++++++++++++ users/app/assets/javascripts/users.js.coffee | 46 -------------- .../controller_extension/authentication.rb | 15 ++++- 3 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 users/app/assets/javascripts/users.js delete mode 100644 users/app/assets/javascripts/users.js.coffee (limited to 'users') diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js new file mode 100644 index 0000000..eed1961 --- /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("/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/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? -- cgit v1.2.3 From fa7b7425e7c53282472c1c9ce1cdc7272f55cfd4 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 2 Jul 2013 23:17:44 -0700 Subject: users engine changes - rewrite of the views, separate email settings to a separate controller, make users_controller html only and v1/users_controller json only. --- users/app/controllers/email_aliases_controller.rb | 18 ++----- users/app/controllers/email_settings_controller.rb | 34 ++++++++++++ users/app/controllers/users_controller.rb | 54 ++++--------------- users/app/controllers/v1/users_controller.rb | 9 ++-- users/app/helpers/users_helper.rb | 36 +------------ users/app/views/_login_or_signup.html.haml | 25 --------- users/app/views/email_settings/edit.html.haml | 38 ++++++++++++++ users/app/views/emails/_email.html.haml | 2 +- users/app/views/emails/edit.html.haml | 5 -- users/app/views/sessions/_admin_nav.html.haml | 6 --- users/app/views/sessions/_nav.html.haml | 13 ----- users/app/views/sessions/_new.html.haml | 7 --- users/app/views/sessions/new.html.haml | 13 ++--- users/app/views/users/_cancel_account.html.haml | 9 ---- users/app/views/users/_edit.html.haml | 37 +++++++++++++ users/app/views/users/_email_aliases.html.haml | 6 --- users/app/views/users/_email_field.html.haml | 1 - .../app/views/users/_email_forward_field.html.haml | 1 - users/app/views/users/_form.html.haml | 11 ---- users/app/views/users/_legend_and_submit.html.haml | 4 -- .../users/_login_and_password_fields.html.haml | 2 - users/app/views/users/_login_field.html.haml | 1 - users/app/views/users/_password_fields.html.haml | 2 - users/app/views/users/_public_key_field.html.haml | 1 - users/app/views/users/edit.html.haml | 7 ++- users/app/views/users/index.html.haml | 31 +++++------ users/app/views/users/new.html.haml | 20 ++++--- users/app/views/users/show.html.haml | 61 ++++++++++++---------- users/config/locales/en.yml | 35 ++++++------- users/config/routes.rb | 3 +- 30 files changed, 224 insertions(+), 268 deletions(-) delete mode 100644 users/app/views/_login_or_signup.html.haml create mode 100644 users/app/views/email_settings/edit.html.haml delete mode 100644 users/app/views/emails/edit.html.haml delete mode 100644 users/app/views/sessions/_admin_nav.html.haml delete mode 100644 users/app/views/sessions/_nav.html.haml delete mode 100644 users/app/views/sessions/_new.html.haml delete mode 100644 users/app/views/users/_cancel_account.html.haml create mode 100644 users/app/views/users/_edit.html.haml delete mode 100644 users/app/views/users/_email_aliases.html.haml delete mode 100644 users/app/views/users/_email_field.html.haml delete mode 100644 users/app/views/users/_email_forward_field.html.haml delete mode 100644 users/app/views/users/_form.html.haml delete mode 100644 users/app/views/users/_legend_and_submit.html.haml delete mode 100644 users/app/views/users/_login_and_password_fields.html.haml delete mode 100644 users/app/views/users/_login_field.html.haml delete mode 100644 users/app/views/users/_password_fields.html.haml delete mode 100644 users/app/views/users/_public_key_field.html.haml (limited to 'users') 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 index e69de29..0261b47 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -0,0 +1,34 @@ +class EmailSettingsController < UsersBaseController + + before_filter :authorize + before_filter :fetch_user + + def edit + @email_alias = LocalEmail.new + end + + def update + @user.attributes = 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 + +end diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 38a69e3..0dbf641 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -1,12 +1,14 @@ -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] - before_filter :authorize_self, :only => [:update] - before_filter :set_anchor, :only => [:edit, :update] before_filter :authorize_admin, :only => [:index] - respond_to :json, :html + respond_to :html def index if params[:query] @@ -14,8 +16,7 @@ class UsersController < ApplicationController else @users = User.by_created_at.descending end - @users = @users.limit(10) - respond_with @users.map(&:login).sort + @users = @users.limit(APP_CONFIG[:pagination_size]) end def new @@ -27,48 +28,15 @@ class UsersController < ApplicationController respond_with @user end - def edit - @email_alias = LocalEmail.new + def show 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) + def edit end def destroy @user.destroy - redirect_to admin? ? users_path : root_path + redirect_to admin? ? users_path : login_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) - 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..e7516bc 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -1,8 +1,9 @@ module V1 - class UsersController < ApplicationController + class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token before_filter :authorize, :only => [:update] + before_filter :fetch_user, :only => [:update] respond_to :json @@ -12,9 +13,11 @@ module V1 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 559b3f7..f56faab 100644 --- a/users/app/helpers/users_helper.rb +++ b/users/app/helpers/users_helper.rb @@ -1,39 +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/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' + 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/views/_login_or_signup.html.haml b/users/app/views/_login_or_signup.html.haml deleted file mode 100644 index b353526..0000000 --- a/users/app/views/_login_or_signup.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -// -// displays a little widget to login or sign up -// - -%ul.nav.nav-tabs - %li.active - %a{:href => ''}= t(:login) - %li - = link_to t(:signup), new_user_path - -= render 'sessions/new' - -// -// this is nice, but it doesn't work because both forms have the same names for fields. -// -// %ul.nav.nav-tabs -// %li.active -// %a{:href => '#login', 'data-toggle' => 'tab'}= t(:login) -// %li -// %a{:href => '#signup', 'data-toggle' => 'tab'}= t(:signup) -// .tab-content -// #login.tab-pane.active -// = render 'sessions/new' -// #signup.tab-pane -// = render 'users/new' 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/emails/edit.html.haml b/users/app/views/emails/edit.html.haml deleted file mode 100644 index b44b569..0000000 --- a/users/app/views/emails/edit.html.haml +++ /dev/null @@ -1,5 +0,0 @@ - - -= 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 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 deleted file mode 100644 index 640fec5..0000000 --- a/users/app/views/sessions/_new.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- @session ||= Session.new -= simple_form_for @session, :validate => true, :html => { :id => :new_session, :class => '' } do |f| - = 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' - // = f.button :submit, :value => t(:login), :class => 'btn-primary' \ No newline at end of file diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml index 960919a..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 + = 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..adee8a4 --- /dev/null +++ b/users/app/views/users/_edit.html.haml @@ -0,0 +1,37 @@ +-# +-# 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) 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 e58c36f..0000000 --- a/users/app/views/users/_login_field.html.haml +++ /dev/null @@ -1 +0,0 @@ -= f.input :login, :label => t(:username), :required => false, :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 7b3358d..0000000 --- a/users/app/views/users/_password_fields.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } -= f.input :password_confirmation, :required => false, :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/edit.html.haml b/users/app/views/users/edit.html.haml index 4e70d69..f06df44 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,3 +1,6 @@ -= user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user -= render 'cancel_account' += render 'edit' + + +=# user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user +=# render 'cancel_account' diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 9e6a179..254e177 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -1,17 +1,14 @@ -.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, "", :class => "user typeahead span2 search-query", :autocomplete => :off + %button.btn{:type => :submit} Search + +%table.table.table-hover + %tr + %th Login + %th Created + %th Action + = render @users.all + diff --git a/users/app/views/users/new.html.haml b/users/app/views/users/new.html.haml index 7d29de2..f8d14b5 100644 --- a/users/app/views/users/new.html.haml +++ b/users/app/views/users/new.html.haml @@ -1,11 +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} + = 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-primary' - = link_to t(:cancel), root_url, :class => :btn + = 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 056ed57..dc5e015 100644 --- a/users/app/views/users/show.html.haml +++ b/users/app/views/users/show.html.haml @@ -1,31 +1,34 @@ -.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'] - - fields.each do |field| += render 'edit' + +-# + .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'] + - fields.each do |field| + %dt + = field.titleize + %dd + = user_field(field) %dt - = field.titleize + =t :email_aliases %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 + - 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 diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml index 3c42b55..63ac692 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -9,28 +9,26 @@ en: login: "Log In" username: "Username" password: "Password" - login_message: "Please login with your account." + change_password: "Change Password" + login_message: "Please log in with your account." invalid_user_pass: "Not a valid username/password combination" all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." update_login_and_password: "Update Login and Password" - cancel_account: "Cancel your account" - remove_account: "Remove Account" - admin_cancel_account: "Cancel the account %{username}" + destroy_my_account: "Destroy my account" + destroy_account_info: "This will permanently destroy your account and all the data associated with it. Proceed with caution!" + admin_destroy_account: "Destroy the account %{username}" set_email_address: "Set email address" - forward_email: "Forward email" - email_aliases: "Email aliases" + forward_email: "Forward Email" + email_aliases: "Email Aliases" public_key: "Public Key" - add_email_alias: "Add email alias" - confirm_question: "Are you sure?" + add_email_alias: "Add Email Alias" user_updated_successfully: "Settings have been updated successfully." user_created_successfully: "Successfully created your account." - email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'." - use_ascii_key: "Use ASCII-armored OpenPGP key" - can_retype_old_password: "Retype your old password if you would like to keep that" - associated_email: "The associated email address is" - cookie_disabled_warning: "You have cookies disabled. You will not be able to login until you enable cookies." - js_required: "We are sorry, but this doesn't work without javascript enabled. This is for security reasons." - + email_alias_destroyed_successfully: "Removed email alias %{alias}." + use_ascii_key: "OpenPGP public key. Do not change this value unless you know what you are doing." + advanced_options: "Advanced Options" + not_authorized: "Sorry, but you are not authorized to perform that action." + not_authorized_login: "Please log in to perform that action." activemodel: models: user: @@ -39,11 +37,12 @@ en: simple_form: labels: user: - email_forward: "Email forward" + email_forward: "Email Forward" hints: user: - email_forward: "Forward all emails to this address" - email: "Your leap web email address" + email_forward: > + Forward all email messages to this address. Messages will be encrypted before being forwarded. + This is an option for advanced users who are familar with OpenPGP. placeholders: user: email_forward: "my_other_email@domain.net" diff --git a/users/config/routes.rb b/users/config/routes.rb index d07cda9..9eff2a1 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update] + resources :users, :only => [:create, :update, :destroy] end get "login" => "sessions#new", :as => "login" @@ -16,7 +16,6 @@ Rails.application.routes.draw do resources :users do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] - resource :account_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ end -- cgit v1.2.3 From 89ad6bd802f9e57c687e8cdb8593c3984e2fbd1b Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:33:09 -0700 Subject: fix user typeahead --- users/app/assets/javascripts/users.js | 4 ++-- users/app/controllers/v1/users_controller.rb | 12 +++++++++++- users/app/views/users/index.html.haml | 13 ++++++------- users/config/routes.rb | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) (limited to 'users') diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js index eed1961..1d05692 100644 --- a/users/app/assets/javascripts/users.js +++ b/users/app/assets/javascripts/users.js @@ -10,7 +10,7 @@ }; poll_users = function(query, process) { - return $.get("/users.json", { + return $.get("/1/users.json", { query: query }).done(process); }; @@ -66,7 +66,7 @@ $('#new_session').submit(srp.login); $('#update_login_and_password').submit(prevent_default); $('#update_login_and_password').submit(srp.update); - return $('.user.typeahead').typeahead({ + return $('#user-typeahead').typeahead({ source: poll_users }); }); diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e7516bc..e117fc7 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -2,11 +2,21 @@ module V1 class UsersController < UsersBaseController skip_before_filter :verify_authenticity_token - before_filter :authorize, :only => [:update] 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? diff --git a/users/app/views/users/index.html.haml b/users/app/views/users/index.html.haml index 254e177..fc1001e 100644 --- a/users/app/views/users/index.html.haml +++ b/users/app/views/users/index.html.haml @@ -2,13 +2,12 @@ = 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 + = text_field_tag :query, params[:query], :id => 'user-typeahead', :class => "search-query", :autocomplete => :off + %button.btn{:type => :submit}= t(:search) -%table.table.table-hover +%table.table.table-striped %tr - %th Login - %th Created - %th Action + %th= t(:username) + %th= t(:created) + %th= t(:updated) = render @users.all - diff --git a/users/config/routes.rb b/users/config/routes.rb index 9eff2a1..693ae7a 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -5,7 +5,7 @@ Rails.application.routes.draw do defaults: {format: 'json'} } do resources :sessions, :only => [:new, :create, :update] delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update, :destroy] + resources :users, :only => [:create, :update, :destroy, :index] end get "login" => "sessions#new", :as => "login" -- cgit v1.2.3 From 03fc85ad20e91964267dfcdaab9e3036c5702689 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:06 -0700 Subject: users - make a nice overview page (well, nice enough) and better users index/search. --- users/app/controllers/users_controller.rb | 9 +++++++-- users/app/views/overviews/show.html.haml | 27 +++++++++++++++------------ users/app/views/users/_user.html.haml | 12 +++--------- users/config/locales/en.yml | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 23 deletions(-) (limited to 'users') diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 0dbf641..81336be 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -12,11 +12,16 @@ class UsersController < UsersBaseController 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(APP_CONFIG[:pagination_size]) + @users = @users.limit(100) end def new diff --git a/users/app/views/overviews/show.html.haml b/users/app/views/overviews/show.html.haml index eda9899..b8ad814 100644 --- a/users/app/views/overviews/show.html.haml +++ b/users/app/views/overviews/show.html.haml @@ -1,15 +1,18 @@ -%p - Username: - = @user.login +.overview -%p - User since: - = @user.created_at + %h2.first= t(:overview_welcome, :username => @user.login) -%p - Last update: - = @user.updated_at + - if admin? + %p + = t(:created) + = @user.created_at + %br + = t(:updated) + = @user.updated_at -%p - Quota: - N/A \ No newline at end of file + %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/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/config/locales/en.yml b/users/config/locales/en.yml index 63ac692..b880887 100644 --- a/users/config/locales/en.yml +++ b/users/config/locales/en.yml @@ -29,6 +29,20 @@ en: advanced_options: "Advanced Options" not_authorized: "Sorry, but you are not authorized to perform that action." not_authorized_login: "Please log in to perform that action." + search: "Search" + + # + # overview + # + overview_welcome: "Welcome %{username}." + overview_intro: "From this user control panel, you can:" + overview_tickets: "Create and check support tickets." + overview_email: "Modify email settings." + overview_account: "Change your password or delete your account." + + # + # rails + # activemodel: models: user: -- cgit v1.2.3 From 2d36a6b68099af39f2bc84a32d67b83f6041ca28 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:34:29 -0700 Subject: test - we allow updating of username via api now --- users/test/integration/api/account_flow_test.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'users') diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb index 1698105..2e45367 100644 --- a/users/test/integration/api/account_flow_test.rb +++ b/users/test/integration/api/account_flow_test.rb @@ -88,10 +88,11 @@ class AccountFlowTest < RackTest server_auth = @srp.authenticate(self) test_public_key = 'asdlfkjslfdkjasd' original_login = @user.login - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => 'failed_login_name'}, :format => :json + new_login = 'zaph' + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => test_public_key, :login => new_login}, :format => :json @user.reload assert_equal test_public_key, @user.public_key - assert_equal original_login, @user.login + assert_equal new_login, @user.login # eventually probably want to remove most of this into a non-integration functional test # should not overwrite public key: put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:blee => :blah}, :format => :json -- cgit v1.2.3 From 290d367ddb064c0aea4e0447441776fd69e29f6c Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 01:45:41 -0700 Subject: allow forms with blank email forward. --- users/app/controllers/email_settings_controller.rb | 9 ++++++++- users/app/models/user.rb | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'users') diff --git a/users/app/controllers/email_settings_controller.rb b/users/app/controllers/email_settings_controller.rb index 0261b47..f7d85be 100644 --- a/users/app/controllers/email_settings_controller.rb +++ b/users/app/controllers/email_settings_controller.rb @@ -8,7 +8,7 @@ class EmailSettingsController < UsersBaseController end def update - @user.attributes = params[:user] + @user.attributes = cleanup_params(params[:user]) if @user.changed? if @user.save flash[:notice] = t(:changes_saved) @@ -31,4 +31,11 @@ class EmailSettingsController < UsersBaseController 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/models/user.rb b/users/app/models/user.rb index 5c849f0..3459520 100644 --- a/users/app/models/user.rb +++ b/users/app/models/user.rb @@ -42,6 +42,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! -- cgit v1.2.3 From 64bacc45ea1a023b154b07ec0790f762a79d20d5 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 02:44:11 -0700 Subject: user tests -- user update has been moved entirely to api controller, so fix tests to reflect this. --- users/app/controllers/users_controller.rb | 5 -- users/app/controllers/v1/users_controller.rb | 1 - users/config/routes.rb | 2 +- users/test/functional/users_controller_test.rb | 63 -------------------- users/test/functional/v1/users_controller_test.rb | 70 +++++++++++++++++++++++ users/test/support/auth_test_helper.rb | 16 ++++-- 6 files changed, 83 insertions(+), 74 deletions(-) create mode 100644 users/test/functional/v1/users_controller_test.rb (limited to 'users') diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 81336be..5d45db5 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -28,11 +28,6 @@ class UsersController < UsersBaseController @user = User.new end - def create - @user = User.create(params[:user]) - respond_with @user - end - def show end diff --git a/users/app/controllers/v1/users_controller.rb b/users/app/controllers/v1/users_controller.rb index e117fc7..fda56f2 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/users/app/controllers/v1/users_controller.rb @@ -23,7 +23,6 @@ module V1 end def update - @user = User.find_by_param(params[:id]) @user.update_attributes params[:user] if @user.valid? flash[:notice] = t(:user_updated_successfully) diff --git a/users/config/routes.rb b/users/config/routes.rb index 693ae7a..b6d583e 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -13,7 +13,7 @@ Rails.application.routes.draw do resources :sessions, :only => [:new, :create, :update] get "signup" => "users#new", :as => "signup" - resources :users do + resources :users, :except => [:create, :update] do resource :overview, :only => [:show] resource :email_settings, :only => [:edit, :update] resources :email_aliases, :only => [:destroy], :id => /.*/ diff --git a/users/test/functional/users_controller_test.rb b/users/test/functional/users_controller_test.rb index 7f81c59..92a5f6c 100644 --- a/users/test/functional/users_controller_test.rb +++ b/users/test/functional/users_controller_test.rb @@ -79,33 +79,6 @@ class UsersControllerTest < ActionController::TestCase assert_redirected_to users_path end - test "should create new user" do - user_attribs = record_attributes_for :user - user = User.new(user_attribs) - User.expects(:create).with(user_attribs).returns(user) - - - post :create, :user => user_attribs, :format => :json - - - assert_nil session[:user_id] - assert_json_response user - assert_response :success - end - - test "should redirect to signup form on failed attempt" do - user_attribs = record_attributes_for :user - user_attribs.slice!('login') - user = User.new(user_attribs) - assert !user.valid? - User.expects(:create).with(user_attribs).returns(user) - - post :create, :user => user_attribs, :format => :json - - assert_json_error user.errors.messages - assert_response 422 - end - test "should get edit view" do user = find_record :user @@ -115,34 +88,6 @@ class UsersControllerTest < ActionController::TestCase assert_equal user, assigns[:user] end - test "user can change settings" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - user.expects(:attributes=).with(changed_attribs) - user.expects(:changed?).returns(true) - user.expects(:save).returns(true) - - login user - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_equal user, assigns[:user] - assert_response 204 - assert_equal " ", @response.body - end - - # Eventually, admin will be able to update some user fields - test "admin cannot update user" do - user = find_record :user - changed_attribs = record_attributes_for :user_with_settings - - login :is_admin? => true - put :update, :user => changed_attribs, :id => user.id, :format => :json - - assert_response :redirect - assert_access_denied - - end - test "admin can destroy user" do user = find_record :user user.expects(:destroy) @@ -189,14 +134,6 @@ class UsersControllerTest < ActionController::TestCase assert_access_denied end - test "admin can autocomplete users" do - login :is_admin? => true - get :index, :format => :json - - assert_response :success - assert assigns(:users) - end - test "admin can search users" do login :is_admin? => true get :index, :query => "a" diff --git a/users/test/functional/v1/users_controller_test.rb b/users/test/functional/v1/users_controller_test.rb new file mode 100644 index 0000000..0d44e50 --- /dev/null +++ b/users/test/functional/v1/users_controller_test.rb @@ -0,0 +1,70 @@ +require 'test_helper' + +class V1::UsersControllerTest < ActionController::TestCase + + test "user can change settings" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login user + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + assert_equal " ", @response.body + end + + test "admin can update user" do + user = find_record :user + changed_attribs = record_attributes_for :user_with_settings + user.expects(:update_attributes).with(changed_attribs) + + login :is_admin? => true + put :update, :user => changed_attribs, :id => user.id, :format => :json + + assert_equal user, assigns[:user] + assert_response 204 + end + + test "user cannot update other user" do + user = find_record :user + login + put :update, :user => record_attributes_for(:user_with_settings), :id => user.id, :format => :json + assert_access_denied + end + + test "should create new user" do + user_attribs = record_attributes_for :user + user = User.new(user_attribs) + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_nil session[:user_id] + assert_json_response user + assert_response :success + end + + test "should redirect to signup form on failed attempt" do + user_attribs = record_attributes_for :user + user_attribs.slice!('login') + user = User.new(user_attribs) + assert !user.valid? + User.expects(:create).with(user_attribs).returns(user) + + post :create, :user => user_attribs, :format => :json + + assert_json_error user.errors.messages + assert_response 422 + end + + test "admin can autocomplete users" do + login :is_admin? => true + get :index, :query => 'a', :format => :json + + assert_response :success + assert assigns(:users) + end + +end diff --git a/users/test/support/auth_test_helper.rb b/users/test/support/auth_test_helper.rb index c0fcf3a..555b5db 100644 --- a/users/test/support/auth_test_helper.rb +++ b/users/test/support/auth_test_helper.rb @@ -20,10 +20,18 @@ module AuthTestHelper def assert_access_denied(denied = true, logged_in = true) if denied - assert_equal({:alert => "Not authorized"}, flash.to_hash) - # todo: eventually probably eliminate separate conditions - assert_redirected_to login_path if !logged_in - assert_redirected_to root_path if logged_in + if @response.content_type == 'application/json' + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + else + if logged_in + assert_equal({:alert => I18n.t(:not_authorized)}, flash.to_hash) + assert_redirected_to root_url + else + assert_equal({:alert => I18n.t(:not_authorized_login)}, flash.to_hash) + assert_redirected_to login_url + end + end else assert flash[:alert].blank? end -- cgit v1.2.3 From 89eace3da1cba0b8dad8cc62cc88bf5ddb1faa5e Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:37:44 -0700 Subject: fix ticket tests, get :admin_user factory to work. --- users/test/factories.rb | 4 +++- users/test/support/stub_record_helper.rb | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'users') diff --git a/users/test/factories.rb b/users/test/factories.rb index 6b094bd..777704b 100644 --- a/users/test/factories.rb +++ b/users/test/factories.rb @@ -13,7 +13,9 @@ FactoryGirl.define do end factory :admin_user do - is_admin? true + after(:build) do |admin| + admin.stubs(:is_admin?).returns(true) + end end end end diff --git a/users/test/support/stub_record_helper.rb b/users/test/support/stub_record_helper.rb index 168a827..8aa1973 100644 --- a/users/test/support/stub_record_helper.rb +++ b/users/test/support/stub_record_helper.rb @@ -1,15 +1,18 @@ module StubRecordHelper - # Will expect find_by_param or find_by_id to be called on klass and + # + # We will stub find_by_param or find_by_id to be called on klass and # return the record given. + # # If no record is given but a hash or nil will create a stub based on # that instead and returns the stub. + # def find_record(factory, attribs_hash = {}) - attribs_hash.reverse_merge!(:id => Random.rand(10000).to_s) + attribs_hash = attribs_hash.reverse_merge(:id => Random.rand(10000).to_s) record = stub_record factory, attribs_hash klass = record.class finder = klass.respond_to?(:find_by_param) ? :find_by_param : :find - klass.expects(finder).with(record.to_param.to_s).returns(record) + klass.stubs(finder).with(record.to_param.to_s).returns(record) return record end -- cgit v1.2.3 From 72db63341a9456c1b9cbd2932c58185b1638f408 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 03:38:00 -0700 Subject: remove empty readme files --- users/README.rdoc | 3 --- users/Readme.md | 0 2 files changed, 3 deletions(-) delete mode 100644 users/README.rdoc delete mode 100644 users/Readme.md (limited to 'users') diff --git a/users/README.rdoc b/users/README.rdoc deleted file mode 100644 index 9fb44c1..0000000 --- a/users/README.rdoc +++ /dev/null @@ -1,3 +0,0 @@ -= LeapWebUsers - -This project rocks and uses MIT-LICENSE. \ No newline at end of file diff --git a/users/Readme.md b/users/Readme.md deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3 From 309bca0b3b2da89cce47da420c87d52e62562d95 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:18:17 -0700 Subject: remove commented out code. --- users/app/views/users/edit.html.haml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'users') diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml index f06df44..08e9dc3 100644 --- a/users/app/views/users/edit.html.haml +++ b/users/app/views/users/edit.html.haml @@ -1,6 +1 @@ -= render 'edit' - - -=# user_form_with 'login_and_password_fields', :legend => :update_login_and_password if @user == current_user -=# render 'cancel_account' - += render 'edit' \ No newline at end of file -- cgit v1.2.3 From 58dc84bb75bf38319b52c821f39fd8017b46ea77 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:23:22 -0700 Subject: fix broken users gemspec --- users/leap_web_users.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'users') diff --git a/users/leap_web_users.gemspec b/users/leap_web_users.gemspec index c57937f..013b44a 100644 --- a/users/leap_web_users.gemspec +++ b/users/leap_web_users.gemspec @@ -11,8 +11,8 @@ Gem::Specification.new do |s| s.homepage = "http://www.leap.se" s.summary = "User registration and authorization for the leap platform" s.description = "This this plugin for the leap platform provides user signup and login. It uses Secure Remote Password for the authentication." - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] + + s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile"] s.test_files = Dir["test/**/*"] s.add_dependency "leap_web_core", LeapWeb::VERSION -- cgit v1.2.3 From 0d95d40616a6b23d848d1fe69d68a14c69280674 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 4 Jul 2013 04:26:31 -0700 Subject: redirect to root after user destroy --- users/app/controllers/users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users') diff --git a/users/app/controllers/users_controller.rb b/users/app/controllers/users_controller.rb index 5d45db5..4ce970b 100644 --- a/users/app/controllers/users_controller.rb +++ b/users/app/controllers/users_controller.rb @@ -36,7 +36,7 @@ class UsersController < UsersBaseController def destroy @user.destroy - redirect_to admin? ? users_path : login_path + redirect_to admin? ? users_url : root_url end end -- cgit v1.2.3 From cc0ffb5511ee233574495d683178f71885a36b7e Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 5 Jul 2013 15:14:23 -0700 Subject: remove unused user views --- users/app/views/users/_new.html.haml | 7 ------- users/app/views/users/show.html.haml | 35 +---------------------------------- 2 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 users/app/views/users/_new.html.haml (limited to 'users') diff --git a/users/app/views/users/_new.html.haml b/users/app/views/users/_new.html.haml deleted file mode 100644 index 3d0f2ac..0000000 --- a/users/app/views/users/_new.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- @user ||= User.new -= user_form do |f| - = render :partial => 'users/login_field', :locals => {:f => f} - = render :partial => 'users/password_fields', :locals => {:f => f} - .form-actions - = f.button :submit, :value => t(:signup), :class => '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 dc5e015..08e9dc3 100644 --- a/users/app/views/users/show.html.haml +++ b/users/app/views/users/show.html.haml @@ -1,34 +1 @@ -= render 'edit' - --# - .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'] - - 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' \ No newline at end of file -- cgit v1.2.3 From 84acdd9133dd30d88b42d63b08d25067e168980d Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 6 Jul 2013 17:17:35 -0700 Subject: updated srp_js submodule --- users/app/assets/javascripts/srp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'users') diff --git a/users/app/assets/javascripts/srp b/users/app/assets/javascripts/srp index e7a0b83..926a5d5 160000 --- a/users/app/assets/javascripts/srp +++ b/users/app/assets/javascripts/srp @@ -1 +1 @@ -Subproject commit e7a0b830b8f994316a560001a9e7397422b184b1 +Subproject commit 926a5d5960db51903e33c8496487da59f9f41242 -- cgit v1.2.3