summaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
authorAzul <azul@leap.se>2013-10-10 09:52:16 +0200
committerAzul <azul@leap.se>2013-10-10 09:52:16 +0200
commitb676e6e6f5367d1be540af817062a77ee3fe7f00 (patch)
tree107c50e838d3fe2feb7da932869a9aabc62ce46b /users
parentb60a75d8cbe25ac47bb037e9e54a7cf4e2ba4e1f (diff)
parenteaedf19e2e54ccb9933caa8dc21df13e48609b18 (diff)
Merge remote-tracking branch 'leap/develop'
Diffstat (limited to 'users')
m---------users/app/assets/javascripts/srp0
-rw-r--r--users/app/assets/javascripts/users.js31
-rw-r--r--users/app/controllers/v1/sessions_controller.rb1
-rw-r--r--users/app/models/email.rb6
-rw-r--r--users/app/models/identity.rb18
-rw-r--r--users/app/models/local_email.rb4
-rw-r--r--users/app/models/login_format_validation.rb8
-rw-r--r--users/app/views/users/_edit.html.haml7
-rw-r--r--users/lib/warden/strategies/secure_remote_password.rb1
-rw-r--r--users/test/integration/browser/account_test.rb36
-rw-r--r--users/test/unit/identity_test.rb20
11 files changed, 120 insertions, 12 deletions
diff --git a/users/app/assets/javascripts/srp b/users/app/assets/javascripts/srp
-Subproject 9c61d52f1f975ec0eefe5b4a0b71ac529300cbe
+Subproject d22bf3b9fe2fd31192e1e1b358e97e5a0f3f90b
diff --git a/users/app/assets/javascripts/users.js b/users/app/assets/javascripts/users.js
index 4c9b510..aaeba6e 100644
--- a/users/app/assets/javascripts/users.js
+++ b/users/app/assets/javascripts/users.js
@@ -3,7 +3,12 @@
// LOCAL FUNCTIONS
//
- var poll_users, prevent_default, form_failed, form_passed, clear_errors;
+ var poll_users,
+ prevent_default,
+ form_failed,
+ form_passed,
+ clear_errors,
+ update_user;
prevent_default = function(event) {
return event.preventDefault();
@@ -19,6 +24,27 @@
return $('#messages').empty();
};
+ update_user = function(submitEvent) {
+ var form = submitEvent.target;
+ var token = form.dataset.token;
+ var url = form.action;
+ var req = $.ajax({
+ url: url,
+ type: 'PUT',
+ headers: { Authorization: 'Token token="' + token + '"' },
+ data: $(form).serialize()
+ });
+ req.done( function() {
+ $(form).find('input[type="submit"]').button('reset');
+ });
+ };
+
+ markAsSubmitted = function(submitEvent) {
+ var form = submitEvent.target;
+ $(form).addClass('submitted')
+ // bootstrap loading state:
+ $(form).find('input[type="submit"]').button('loading');
+ };
//
// PUBLIC FUNCTIONS
@@ -70,12 +96,15 @@
//
$(document).ready(function() {
+ $('form').submit(markAsSubmitted);
$('#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);
+ $('#update_pgp_key').submit(prevent_default);
+ $('#update_pgp_key').submit(update_user);
return $('#user-typeahead').typeahead({
source: poll_users
});
diff --git a/users/app/controllers/v1/sessions_controller.rb b/users/app/controllers/v1/sessions_controller.rb
index 1b20a82..eb6c322 100644
--- a/users/app/controllers/v1/sessions_controller.rb
+++ b/users/app/controllers/v1/sessions_controller.rb
@@ -24,6 +24,7 @@ module V1
def update
authenticate!
@token = Token.create(:user_id => current_user.id)
+ session[:token] = @token.id
render :json => login_response
end
diff --git a/users/app/models/email.rb b/users/app/models/email.rb
index 1bcff1c..a9a503f 100644
--- a/users/app/models/email.rb
+++ b/users/app/models/email.rb
@@ -3,7 +3,7 @@ class Email < String
validates :email,
:format => {
- :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/,
+ :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, #local part of email is case-sensitive, so allow uppercase letter.
:message => "needs to be a valid email address"
}
@@ -19,4 +19,8 @@ class Email < String
self
end
+ def handle
+ self.split('@').first
+ end
+
end
diff --git a/users/app/models/identity.rb b/users/app/models/identity.rb
index 355f67a..e0a24e9 100644
--- a/users/app/models/identity.rb
+++ b/users/app/models/identity.rb
@@ -1,4 +1,5 @@
class Identity < CouchRest::Model::Base
+ include LoginFormatValidation
use_database :identities
@@ -10,6 +11,8 @@ class Identity < CouchRest::Model::Base
validate :unique_forward
validate :alias_available
+ validate :address_local_email
+ validate :destination_email
design do
view :by_user_id
@@ -63,6 +66,11 @@ class Identity < CouchRest::Model::Base
write_attribute('keys', keys.merge(type => value))
end
+ # for LoginFormatValidation
+ def login
+ self.address.handle
+ end
+
protected
def unique_forward
@@ -79,4 +87,14 @@ class Identity < CouchRest::Model::Base
end
end
+ def address_local_email
+ return if address.valid? #this ensures it is LocalEmail
+ self.errors.add(:address, address.errors.messages[:email].first) #assumes only one error
+ end
+
+ def destination_email
+ return if destination.valid? #this ensures it is Email
+ self.errors.add(:destination, destination.errors.messages[:email].first) #assumes only one error #TODO
+ end
+
end
diff --git a/users/app/models/local_email.rb b/users/app/models/local_email.rb
index c1f7c11..6303bb6 100644
--- a/users/app/models/local_email.rb
+++ b/users/app/models/local_email.rb
@@ -20,10 +20,6 @@ class LocalEmail < Email
[handle]
end
- def handle
- gsub(/@#{domain}/i, '')
- end
-
def domain
LocalEmail.domain
end
diff --git a/users/app/models/login_format_validation.rb b/users/app/models/login_format_validation.rb
index 1d02bd1..c1fcf70 100644
--- a/users/app/models/login_format_validation.rb
+++ b/users/app/models/login_format_validation.rb
@@ -1,19 +1,21 @@
module LoginFormatValidation
extend ActiveSupport::Concern
+ #TODO: Probably will replace this. Playing with using it for aliases too, but won't want it connected to login field.
+
included do
# Have multiple regular expression validations so we can get specific error messages:
validates :login,
:format => { :with => /\A.{2,}\z/,
- :message => "Login must have at least two characters"}
+ :message => "Must have at least two characters"}
validates :login,
:format => { :with => /\A[a-z\d_\.-]+\z/,
:message => "Only lowercase letters, digits, . - and _ allowed."}
validates :login,
:format => { :with => /\A[a-z].*\z/,
- :message => "Login must begin with a lowercase letter"}
+ :message => "Must begin with a lowercase letter"}
validates :login,
:format => { :with => /\A.*[a-z\d]\z/,
- :message => "Login must end with a letter or digit"}
+ :message => "Must end with a letter or digit"}
end
end
diff --git a/users/app/views/users/_edit.html.haml b/users/app/views/users/_edit.html.haml
index 5f74d32..9d2473b 100644
--- a/users/app/views/users/_edit.html.haml
+++ b/users/app/views/users/_edit.html.haml
@@ -10,7 +10,8 @@
-# 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}
+
+- form_options = {:url => '/not-used', :html => {:class => user_form_class('form-horizontal'), :id => 'update_login_and_password', :data => {token: session[:token]}}, :validate => true}
= simple_form_for @user, form_options do |f|
%legend= t(:change_password)
= hidden_field_tag 'user_param', @user.to_param
@@ -28,13 +29,13 @@
-# this will be replaced by a identities controller/view at some point
-#
-- form_options = {:html => {:class => user_form_class('form-horizontal'), :id => 'update_pgp_key'}, :validate => true}
+- form_options = {:html => {:class => user_form_class('form-horizontal'), :id => 'update_pgp_key', :data => {token: session[:token]}}, :validate => true}
= simple_form_for [:api, @user], form_options do |f|
%legend= t(:advanced_options)
= f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "full-width", :rows => 4}
.control-group
.controls
- = f.submit t(:save), :class => 'btn'
+ = f.submit t(:save), :class => 'btn', :data => {"loading-text" => "Saving..."}
-#
-# DESTROY ACCOUNT
diff --git a/users/lib/warden/strategies/secure_remote_password.rb b/users/lib/warden/strategies/secure_remote_password.rb
index 4688fcd..2c334c6 100644
--- a/users/lib/warden/strategies/secure_remote_password.rb
+++ b/users/lib/warden/strategies/secure_remote_password.rb
@@ -31,6 +31,7 @@ module Warden
Rails.logger.warn "Login attempt failed."
Rails.logger.debug debug_info
Rails.logger.debug "Received: #{params['client_auth']}"
+ session.delete(:handshake)
fail!(:base => "invalid_user_pass")
end
end
diff --git a/users/test/integration/browser/account_test.rb b/users/test/integration/browser/account_test.rb
index 8c2c997..1deda45 100644
--- a/users/test/integration/browser/account_test.rb
+++ b/users/test/integration/browser/account_test.rb
@@ -24,8 +24,44 @@ class AccountTest < BrowserIntegrationTest
fill_in 'Password', with: password
click_on 'Log In'
assert page.has_content?("Welcome #{username}")
+ User.find_by_login(username).account.destroy
end
+ test "change password" do
+ username, password = submit_signup
+ click_on "Account Settings"
+ within('#update_login_and_password') do
+ fill_in 'Password', with: "other password"
+ fill_in 'Password confirmation', with: "other password"
+ click_on 'Save'
+ end
+ click_on 'Logout'
+ click_on 'Log In'
+ fill_in 'Username', with: username
+ fill_in 'Password', with: "other password"
+ click_on 'Log In'
+ assert page.has_content?("Welcome #{username}")
+ User.find_by_login(username).account.destroy
+ end
+
+ test "change pgp key" do
+ pgp_key = "My PGP Key Stub"
+ username, password = submit_signup
+ click_on "Account Settings"
+ within('#update_pgp_key') do
+ fill_in 'Public key', with: pgp_key
+ click_on 'Save'
+ end
+ page.assert_selector 'input[value="Saving..."]'
+ # at some point we're done:
+ page.assert_no_selector 'input[value="Saving..."]'
+ assert page.has_field? 'Public key', with: pgp_key
+ user = User.find_by_login(username)
+ assert_equal pgp_key, user.public_key
+ user.account.destroy
+ end
+
+
# trying to seed an invalid A for srp login
test "detects attempt to circumvent SRP" do
user = FactoryGirl.create :user
diff --git a/users/test/unit/identity_test.rb b/users/test/unit/identity_test.rb
index fa88315..0842a77 100644
--- a/users/test/unit/identity_test.rb
+++ b/users/test/unit/identity_test.rb
@@ -70,6 +70,26 @@ class IdentityTest < ActiveSupport::TestCase
id.destroy
end
+ test "fail to add non-local email address as identity address" do
+ id = Identity.for @user, address: forward_address
+ assert !id.valid?
+ assert_match /needs to end in/, id.errors[:address].first
+ end
+
+ test "alias must meet same conditions as login" do
+ id = Identity.create_for @user, address: alias_name.capitalize
+ assert !id.valid?
+ #hacky way to do this, but okay for now:
+ assert id.errors.messages.flatten(2).include? "Must begin with a lowercase letter"
+ assert id.errors.messages.flatten(2).include? "Only lowercase letters, digits, . - and _ allowed."
+ end
+
+ test "destination must be valid email address" do
+ id = Identity.create_for @user, address: @user.email_address, destination: 'ASKJDLFJD'
+ assert !id.valid?
+ assert id.errors.messages[:destination].include? "needs to be a valid email address"
+ end
+
def alias_name
@alias_name ||= Faker::Internet.user_name
end