summaryrefslogtreecommitdiff
path: root/users/test/integration
diff options
context:
space:
mode:
Diffstat (limited to 'users/test/integration')
-rw-r--r--users/test/integration/api/account_flow_test.rb42
-rwxr-xr-xusers/test/integration/api/python/flow_with_srp.py96
-rw-r--r--users/test/integration/browser/account_test.rb20
3 files changed, 110 insertions, 48 deletions
diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb
index 4c94389..e41befa 100644
--- a/users/test/integration/api/account_flow_test.rb
+++ b/users/test/integration/api/account_flow_test.rb
@@ -5,6 +5,7 @@ class AccountFlowTest < RackTest
setup do
@login = "integration_test_user"
+ Identity.find_by_address(@login + '@' + APP_CONFIG[:domain]).tap{|i| i.destroy if i}
User.find_by_login(@login).tap{|u| u.destroy if u}
@password = "srp, verify me!"
@srp = SRP::Client.new @login, :password => @password
@@ -18,7 +19,10 @@ class AccountFlowTest < RackTest
end
teardown do
- @user.destroy if @user
+ if @user.reload
+ @user.identity.destroy
+ @user.destroy
+ end
Warden.test_reset!
end
@@ -74,25 +78,45 @@ class AccountFlowTest < RackTest
assert_nil server_auth
end
+ test "update password via api" do
+ @srp.authenticate(self)
+ @password = "No! Verify me instead."
+ @srp = SRP::Client.new @login, :password => @password
+ @user_params = {
+ # :login => @login,
+ :password_verifier => @srp.verifier.to_s(16),
+ :password_salt => @srp.salt.to_s(16)
+ }
+ put "http://api.lvh.me:3000/1/users/" + @user.id + '.json',
+ :user => @user_params,
+ :format => :json
+ server_auth = @srp.authenticate(self)
+ assert last_response.successful?
+ assert_nil server_auth["errors"]
+ assert server_auth["M2"]
+ end
+
test "update user" do
server_auth = @srp.authenticate(self)
test_public_key = 'asdlfkjslfdkjasd'
original_login = @user.login
new_login = 'zaph'
+ User.find_by_login(new_login).try(:destroy)
+ Identity.by_address.key(new_login + '@' + APP_CONFIG[:domain]).each do |identity|
+ identity.destroy
+ end
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 new_login, @user.login
+ assert last_response.successful?
+ assert_equal test_public_key, Identity.for(@user).keys[:pgp]
+ # does not change login if no password_verifier is present
+ assert_equal original_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
- @user.reload
- assert_equal test_public_key, @user.public_key
+ assert_equal test_public_key, Identity.for(@user).keys[:pgp]
# should overwrite public key:
put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => nil}, :format => :json
- # TODO: not sure why i need this, but when public key is removed, the DB is updated but @user.reload doesn't seem to actually reload.
- @user = User.find(@user.id) # @user.reload
- assert_nil @user.public_key
+ assert_nil Identity.for(@user).keys[:pgp]
end
end
diff --git a/users/test/integration/api/python/flow_with_srp.py b/users/test/integration/api/python/flow_with_srp.py
index 7b741d6..9fc168b 100755
--- a/users/test/integration/api/python/flow_with_srp.py
+++ b/users/test/integration/api/python/flow_with_srp.py
@@ -11,68 +11,86 @@ import binascii
safe_unhexlify = lambda x: binascii.unhexlify(x) if (len(x) % 2 == 0) else binascii.unhexlify('0'+x)
+# using globals for now
+# server = 'https://dev.bitmask.net/1'
+server = 'http://api.lvh.me:3000/1'
+
+def run_tests():
+ login = 'test_' + id_generator()
+ password = id_generator() + id_generator()
+ usr = srp.User( login, password, srp.SHA256, srp.NG_1024 )
+ print_and_parse(signup(login, password))
+
+ auth = print_and_parse(authenticate(usr))
+ verify_or_debug(auth, usr)
+ assert usr.authenticated()
+
+ usr = change_password(auth['id'], login, auth['token'])
+
+ auth = print_and_parse(authenticate(usr))
+ verify_or_debug(auth, usr)
+ # At this point the authentication process is complete.
+ assert usr.authenticated()
+
# let's have some random name
def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for x in range(size))
-# using globals for a start
-server = 'https://api.bitmask.net:4430/1'
-login = id_generator()
-password = id_generator() + id_generator()
-
-# print ' username = "' + login + '"'
-# print ' password = "' + password + '"'
-
# log the server communication
def print_and_parse(response):
- print response.request.method + ': ' + response.url
- print " " + json.dumps(response.request.data)
+ request = response.request
+ print request.method + ': ' + response.url
+ if hasattr(request, 'data'):
+ print " " + json.dumps(response.request.data)
print " -> " + response.text
- return json.loads(response.text)
+ try:
+ return json.loads(response.text)
+ except ValueError:
+ return None
-def signup(session):
+def signup(login, password):
salt, vkey = srp.create_salted_verification_key( login, password, srp.SHA256, srp.NG_1024 )
- # print ' salt = "' + binascii.hexlify(salt) + '"'
- # print ' v = "' + binascii.hexlify(vkey) + '"'
user_params = {
'user[login]': login,
'user[password_verifier]': binascii.hexlify(vkey),
'user[password_salt]': binascii.hexlify(salt)
}
- return session.post(server + '/users.json', data = user_params, verify = False)
+ return requests.post(server + '/users.json', data = user_params, verify = False)
-usr = srp.User( login, password, srp.SHA256, srp.NG_1024 )
+def change_password(user_id, login, token):
+ password = id_generator() + id_generator()
+ salt, vkey = srp.create_salted_verification_key( login, password, srp.SHA256, srp.NG_1024 )
+ user_params = {
+ 'user[password_verifier]': binascii.hexlify(vkey),
+ 'user[password_salt]': binascii.hexlify(salt)
+ }
+ auth_headers = { 'Authorization': 'Token token="' + token + '"'}
+ print user_params
+ print_and_parse(requests.put(server + '/users/' + user_id + '.json', data = user_params, verify = False, headers = auth_headers))
+ return srp.User( login, password, srp.SHA256, srp.NG_1024 )
-def authenticate(session, login):
+
+def authenticate(usr):
+ session = requests.session()
uname, A = usr.start_authentication()
- # print ' aa = "' + binascii.hexlify(A) + '"'
params = {
'login': uname,
'A': binascii.hexlify(A)
}
init = print_and_parse(session.post(server + '/sessions', data = params, verify=False))
- # print ' b = "' + init['b'] + '"'
- # print ' bb = "' + init['B'] + '"'
M = usr.process_challenge( safe_unhexlify(init['salt']), safe_unhexlify(init['B']) )
- # print ' m = "' + binascii.hexlify(M) + '"'
- return session.put(server + '/sessions/' + login, verify = False,
+ return session.put(server + '/sessions/' + uname, verify = False,
data = {'client_auth': binascii.hexlify(M)})
-session = requests.session()
-user = print_and_parse(signup(session))
-
-# SRP signup would happen here and calculate M hex
-auth = print_and_parse(authenticate(session, user['login']))
-if ( 'errors' in auth ):
- print ' u = "%x"' % usr.u
- print ' x = "%x"' % usr.x
- print ' v = "%x"' % usr.v
- print ' S = "%x"' % usr.S
- print ' K = "' + binascii.hexlify(usr.K) + '"'
- print ' M = "%x"' % usr.M
-else:
- usr.verify_session( safe_unhexlify(auth["M2"]) )
-
-# At this point the authentication process is complete.
-assert usr.authenticated()
+def verify_or_debug(auth, usr):
+ if ( 'errors' in auth ):
+ print ' u = "%x"' % usr.u
+ print ' x = "%x"' % usr.x
+ print ' v = "%x"' % usr.v
+ print ' S = "%x"' % usr.S
+ print ' K = "' + binascii.hexlify(usr.K) + '"'
+ print ' M = "' + binascii.hexlify(usr.M) + '"'
+ else:
+ usr.verify_session( safe_unhexlify(auth["M2"]) )
+run_tests()
diff --git a/users/test/integration/browser/account_test.rb b/users/test/integration/browser/account_test.rb
index ce63baf..b412980 100644
--- a/users/test/integration/browser/account_test.rb
+++ b/users/test/integration/browser/account_test.rb
@@ -20,4 +20,24 @@ class AccountTest < BrowserIntegrationTest
assert_equal '/', current_path
end
+ # trying to seed an invalid A for srp login
+ test "detects attempt to circumvent SRP" do
+ user = FactoryGirl.create :user
+ visit '/sessions/new'
+ fill_in 'Username', with: user.login
+ fill_in 'Password', with: "password"
+ inject_malicious_js
+ click_on 'Log In'
+ assert page.has_content?("Invalid random key")
+ assert page.has_no_content?("Welcome")
+ end
+
+ def inject_malicious_js
+ page.execute_script <<-EOJS
+ var calc = new srp.Calculate();
+ calc.A = function(_a) {return "00";};
+ calc.S = calc.A;
+ srp.session = new srp.Session(null, calc);
+ EOJS
+ end
end