From 389ddf51ef854c6cfa9541c717c857a8563766e4 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 26 Feb 2013 11:40:41 +0100 Subject: git ignore binstubs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3b31e0b..5536c6f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ public/ca.crt public/config/* public/provider.json config/config.yml +bin -- cgit v1.2.3 From 4a92bab4d8c231a17a14afc81c391f9a1f91c063 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 26 Feb 2013 11:42:19 +0100 Subject: api for sessions fixed * now we return the user id on login * allow a destroy request for logging out * added test for api sessions controller --- users/app/controllers/sessions_controller.rb | 2 - users/app/controllers/v1/sessions_controller.rb | 10 +++- users/app/views/v1/sessions/new.json.erb | 3 + users/config/routes.rb | 9 +-- users/leap_web_users.gemspec | 2 +- .../warden/strategies/secure_remote_password.rb | 11 +++- users/test/functional/sessions_controller_test.rb | 4 +- .../test/functional/v1/sessions_controller_test.rb | 68 ++++++++++++++++++++++ 8 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 users/app/views/v1/sessions/new.json.erb create mode 100644 users/test/functional/v1/sessions_controller_test.rb diff --git a/users/app/controllers/sessions_controller.rb b/users/app/controllers/sessions_controller.rb index 0345fbd..01ecff6 100644 --- a/users/app/controllers/sessions_controller.rb +++ b/users/app/controllers/sessions_controller.rb @@ -1,7 +1,5 @@ class SessionsController < ApplicationController - skip_before_filter :verify_authenticity_token - def new @session = Session.new if authentication_errors diff --git a/users/app/controllers/v1/sessions_controller.rb b/users/app/controllers/v1/sessions_controller.rb index 27d10fb..0551ca9 100644 --- a/users/app/controllers/v1/sessions_controller.rb +++ b/users/app/controllers/v1/sessions_controller.rb @@ -18,12 +18,20 @@ module V1 def update authenticate! - render :json => session.delete(:handshake) + render :json => login_response end def destroy logout redirect_to root_path end + + protected + + def login_response + handshake = session.delete(:handshake) + handshake.to_hash.merge(:id => current_user.id) + end + end end diff --git a/users/app/views/v1/sessions/new.json.erb b/users/app/views/v1/sessions/new.json.erb new file mode 100644 index 0000000..36154b8 --- /dev/null +++ b/users/app/views/v1/sessions/new.json.erb @@ -0,0 +1,3 @@ +{ +"errors": <%= raw @errors.to_json %> +} diff --git a/users/config/routes.rb b/users/config/routes.rb index 2cd1740..c50cb15 100644 --- a/users/config/routes.rb +++ b/users/config/routes.rb @@ -1,17 +1,18 @@ Rails.application.routes.draw do constraints :subdomain => "api" do - namespace "api", { module: "V1", + namespace "api", { module: "v1", path: "/1/", defaults: {format: 'json'} } do - resources :sessions, :only => [:new, :create, :update, :destroy] + resources :sessions, :only => [:new, :create, :update] + delete "logout" => "sessions#destroy", :as => "logout" resources :users, :only => [:create, :update] end end get "login" => "sessions#new", :as => "login" - get "logout" => "sessions#destroy", :as => "logout" - resources :sessions, :only => [:new, :create, :update, :destroy] + delete "logout" => "sessions#destroy", :as => "logout" + resources :sessions, :only => [:new, :create, :update] get "signup" => "users#new", :as => "signup" resources :users do diff --git a/users/leap_web_users.gemspec b/users/leap_web_users.gemspec index 0182c1f..c57937f 100644 --- a/users/leap_web_users.gemspec +++ b/users/leap_web_users.gemspec @@ -17,6 +17,6 @@ Gem::Specification.new do |s| s.add_dependency "leap_web_core", LeapWeb::VERSION - s.add_dependency "ruby-srp", "~> 0.1.5" + s.add_dependency "ruby-srp", "~> 0.1.6" s.add_dependency "rails_warden" end diff --git a/users/lib/warden/strategies/secure_remote_password.rb b/users/lib/warden/strategies/secure_remote_password.rb index 483336d..363e6a0 100644 --- a/users/lib/warden/strategies/secure_remote_password.rb +++ b/users/lib/warden/strategies/secure_remote_password.rb @@ -25,10 +25,15 @@ module Warden end def validate! - client = session[:handshake].authenticate(params['client_auth'].hex) - client ? - success!(User.find_by_login(client.username)) : + if client = validate + success!(User.find_by_login(client.username)) + else fail!(:password => "wrong_password") + end + end + + def validate + session[:handshake].authenticate(params['client_auth'].hex) end def initialize! diff --git a/users/test/functional/sessions_controller_test.rb b/users/test/functional/sessions_controller_test.rb index 9df4455..f99c0d7 100644 --- a/users/test/functional/sessions_controller_test.rb +++ b/users/test/functional/sessions_controller_test.rb @@ -47,10 +47,12 @@ class SessionsControllerTest < ActionController::TestCase request.env['warden'].expects(:authenticate!) handshake = stub(:to_json => "JSON") session[:handshake] = handshake + post :update, :id => @user.login, :client_auth => @client_hex + assert_nil session[:handshake] assert_response :success - assert_equal handshake.to_json, @response.body + assert_json_response handshake end test "logout should reset warden user" do diff --git a/users/test/functional/v1/sessions_controller_test.rb b/users/test/functional/v1/sessions_controller_test.rb new file mode 100644 index 0000000..be085ce --- /dev/null +++ b/users/test/functional/v1/sessions_controller_test.rb @@ -0,0 +1,68 @@ +require 'test_helper' + +# This is a simple controller unit test. +# We're stubbing out both warden and srp. +# There's an integration test testing the full rack stack and srp +class V1::SessionsControllerTest < ActionController::TestCase + + setup do + @request.env['HTTP_HOST'] = 'api.lvh.me' + @user = stub :login => "me", :id => 123 + @client_hex = 'a123' + end + + test "renders json" do + request.env['warden'].expects(:winning_strategy) + get :new, :format => :json + assert_response :success + assert_json_error nil + end + + test "renders warden errors" do + strategy = stub :message => {:field => :translate_me} + request.env['warden'].stubs(:winning_strategy).returns(strategy) + I18n.expects(:t).with(:translate_me).at_least_once.returns("translation stub") + get :new, :format => :json + assert_response 422 + assert_json_error :field => "translation stub" + end + + # Warden takes care of parsing the params and + # rendering the response. So not much to test here. + test "should perform handshake" do + request.env['warden'].expects(:authenticate!) + # make sure we don't get a template missing error: + @controller.stubs(:render) + post :create, :login => @user.login, 'A' => @client_hex + end + + test "should authorize" do + request.env['warden'].expects(:authenticate!) + @controller.expects(:current_user).returns(@user) + handshake = stub(:to_hash => {h: "ash"}) + session[:handshake] = handshake + + post :update, :id => @user.login, :client_auth => @client_hex + + assert_nil session[:handshake] + assert_response :success + assert_json_response handshake.to_hash.merge(id: @user.id) + end + + test "logout should reset warden user" do + expect_warden_logout + delete :destroy + assert_response :redirect + assert_redirected_to root_url + end + + def expect_warden_logout + raw = mock('raw session') do + expects(:inspect) + end + request.env['warden'].expects(:raw_session).returns(raw) + request.env['warden'].expects(:logout) + end + + +end -- cgit v1.2.3 From a7722e57ee6e10b578457e880f04349f7f9a0f66 Mon Sep 17 00:00:00 2001 From: jessib Date: Tue, 26 Feb 2013 11:33:11 -0800 Subject: Changes to valid format for usernames. --- users/app/models/user.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/users/app/models/user.rb b/users/app/models/user.rb index e41c2dc..b6e2bad 100644 --- a/users/app/models/user.rb +++ b/users/app/models/user.rb @@ -19,8 +19,8 @@ class User < CouchRest::Model::Base :if => :serverside? validates :login, - :format => { :with => /\A[A-Za-z\d_\.]+\z/, - :message => "Only letters, digits, . and _ allowed" } + :format => { :with => /\A[a-z][a-z\d_\.-]*[a-z\d]\z/, + :message => "Only lowercase letters, digits, . - and _ allowed. Login must have at least 2 characters, and begin with a letter, and end with a letter or digit" } validate :login_is_unique_alias -- cgit v1.2.3 From d656c33422c3d3ac72878e8ddccbd087a48a401c Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 22 Oct 2012 15:36:27 +0200 Subject: added TL;DR - fixed some issues with documentation * using ruby 1.9.3 now * not using leap_ca anymore --- INSTALL.md | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 9e93eb0..ce17f39 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,5 +1,18 @@ # Installation # +## TL;DR ## + +Install git, ruby, rubygems, bundler and couchdb on your system. Then run + +``` +git clone git://github.com/leapcode/leap_web.git +cd leap_web +bundle install +git submodule init +git submodule update +bundle exec rails server +``` + ## Requirements ## The webapp only depends on very basic ruby packages and installs the other requirements as gems through bundler. @@ -9,17 +22,29 @@ The webapp only depends on very basic ruby packages and installs the other requi The following packages need to be installed: * git -* ruby (1.8.7 and 1.9.3 work) +* ruby1.9.3 * rubygems * couchdb +### Code ### + +Simply clone the git repository: + +``` + git clone git://github.com/leapcode/leap_web.git + cd leap_web +``` + ### Gems ### We install most gems we depend upon through [bundler](http://gembundler.com). However the bundler gem needs to be installed and the `bundle` command needs to be available to the user used for deploy. ### Bundler ### -Run `bundle install` to install all the required gems. +Install all the required gems: +``` + bundle install +``` ## Setup ## @@ -32,13 +57,14 @@ We currently use a git submodule to include srp-js. This will soon be replaced b git submodule update ``` -### Cert Distribution ### +### Provider Information ### -The Webapp can hand out certs for the EIP client. These certs are either picked from a pool in CouchDB or from a file. For now you can either run [Leap CA](http://github.com/leapcode/leap_ca) to fill the pool or you can put your certs file in config/cert. - -We also ship provider information through the webapp. For now please add your eip-service.json to the public/config directory. +The leap client fetches provider information via json files from the server. +If you want to use that functionality please add your provider files the public/config directory. ## Running ## -Run `rails server`, `bundle exec rails server` or whatever rack server you prefer. +``` +bundle exec rails server +``` -- cgit v1.2.3 From 044a11e780967d7fee0af5a9736ce7db4cd6007d Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 22 Oct 2012 15:37:26 +0200 Subject: use debugger for ruby 1.9 - not supporting 1.8.7 anymore ruby-debug breaks with 1.9 debugger breaks with 1.8.7 --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 4bf0f3b..56cbf62 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,8 @@ gem 'leap_web_help', :path => 'help' # To use debugger gem 'debugger', :platforms => :mri_19 -gem 'ruby-debug', :platforms => :mri_18 +# ruby 1.8 is not supported anymore +# gem 'ruby-debug', :platforms => :mri_18 # unreleased so far ... but leap_web_certs need it -- cgit v1.2.3 From 1a369be11b776cd75b3c046fa508ea1bca499227 Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 22 Oct 2012 17:18:14 +0200 Subject: seperated troubleshoot from install --- INSTALL.md | 16 ++++++++++++---- TROUBLESHOOT.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 TROUBLESHOOT.md diff --git a/INSTALL.md b/INSTALL.md index ce17f39..4a2a5b9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,10 +1,13 @@ # Installation # +Please see TROUBLESHOOT.md if you run into any issues during install. + ## TL;DR ## -Install git, ruby, rubygems, bundler and couchdb on your system. Then run +Install git, ruby 1.9, rubygems and couchdb on your system. Then run ``` +gem install bundler git clone git://github.com/leapcode/leap_web.git cd leap_web bundle install @@ -13,6 +16,8 @@ git submodule update bundle exec rails server ``` +You will find Leap Web running on `localhost:3000`. Check out the Cert Distribution section below for setting up the cert and server config. + ## Requirements ## The webapp only depends on very basic ruby packages and installs the other requirements as gems through bundler. @@ -37,11 +42,13 @@ Simply clone the git repository: ### Gems ### -We install most gems we depend upon through [bundler](http://gembundler.com). However the bundler gem needs to be installed and the `bundle` command needs to be available to the user used for deploy. +We install most gems we depend upon through [bundler](http://gembundler.com). First install bundler -### Bundler ### +``` + gem install bundler +``` -Install all the required gems: +Then install all the required gems: ``` bundle install ``` @@ -68,3 +75,4 @@ If you want to use that functionality please add your provider files the public/ bundle exec rails server ``` +You'll find Leap Web running on `localhost:3000` diff --git a/TROUBLESHOOT.md b/TROUBLESHOOT.md new file mode 100644 index 0000000..f3db006 --- /dev/null +++ b/TROUBLESHOOT.md @@ -0,0 +1,46 @@ +# Troubleshooting # + +Here are some less common issues you might run into when installing Leap Web. + +## Cannot find Bundler ## + +### Error Messages ### + +`bundle: command not found` + +### Solution ### + +Make sure bundler is installed. `gem list bundler` should list `bundler`. +You also need to be able to access the `bundler` executable in your PATH. + +## Outdated version of rubygems ## + +### Error Messages ### + +`bundler requires rubygems >= 1.3.6` + +### Solution ### + +`gem update --system` will install the latest rubygems + +## Missing development tools ## + +Some required gems will compile C extensions. They need a bunch of utils for this. + +### Error Messages ### + +`make: Command not found` + +### Solution ### + +Install the required tools. For linux the `build-essential` package provides most of them. For Mac OS you probably want the XCode Commandline tools. + +## Missing libraries and headers ## + +Some gem dependencies might not compile because they lack the needed c libraries. + +### Solution ### + +Install the libraries in question including their development files. + + -- cgit v1.2.3 From f053c1c53f00962ee9ca25d591d248e7695e6fa5 Mon Sep 17 00:00:00 2001 From: elijah Date: Wed, 27 Feb 2013 20:54:50 -0800 Subject: change free cert postfix to be a prefix (this is required for how openvpn does common name matching) --- certs/app/models/client_certificate.rb | 3 +-- certs/test/unit/client_certificate_test.rb | 12 ++++++------ config/defaults.yml | 3 +-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/certs/app/models/client_certificate.rb b/certs/app/models/client_certificate.rb index 1bc34c6..13e0318 100644 --- a/certs/app/models/client_certificate.rb +++ b/certs/app/models/client_certificate.rb @@ -66,8 +66,7 @@ class ClientCertificate end def common_name(for_free_cert = false) - random_common_name + - (for_free_cert ? APP_CONFIG[:free_cert_postfix] : '') + (for_free_cert ? APP_CONFIG[:free_cert_prefix] : '') + random_common_name end # diff --git a/certs/test/unit/client_certificate_test.rb b/certs/test/unit/client_certificate_test.rb index bcc61cc..abb5560 100644 --- a/certs/test/unit/client_certificate_test.rb +++ b/certs/test/unit/client_certificate_test.rb @@ -9,16 +9,16 @@ class ClientCertificateTest < ActiveSupport::TestCase assert sample.to_s end - test "free cert has configured postfix" do + test "free cert has configured prefix" do sample = ClientCertificate.new(free: true) - postfix = APP_CONFIG[:free_cert_postfix] - assert sample.cert.subject.common_name.include?(postfix) + prefix = APP_CONFIG[:free_cert_prefix] + assert sample.cert.subject.common_name.starts_with?(prefix) end - test "real cert has no free cert postfix" do + test "real cert has no free cert prefix" do sample = ClientCertificate.new - postfix = APP_CONFIG[:free_cert_postfix] - assert !sample.cert.subject.common_name.include?(postfix) + prefix = APP_CONFIG[:free_cert_prefix] + assert !sample.cert.subject.common_name.starts_with?(prefix) end test "cert issuer matches ca subject" do diff --git a/config/defaults.yml b/config/defaults.yml index 54e4178..d0fb52f 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -8,7 +8,7 @@ cert_options: &cert_options client_cert_bit_size: 2024 client_cert_hash: "SHA256" free_certs_enabled: true - free_cert_postfix: "*Free Cert*" + free_cert_prefix: "FREE" development: <<: *dev_ca @@ -21,7 +21,6 @@ test: <<: *cert_options admins: [admin, admin2] domain: test.me - production: <<: *cert_options -- cgit v1.2.3 From 09389ccdad2ace4c2ae71ba93dc4ad78a520e7dd Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 28 Feb 2013 18:01:51 +0100 Subject: use binstubs to make sure we use the right rails version --- INSTALL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 4a2a5b9..7e95b76 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -10,10 +10,10 @@ Install git, ruby 1.9, rubygems and couchdb on your system. Then run gem install bundler git clone git://github.com/leapcode/leap_web.git cd leap_web -bundle install git submodule init git submodule update -bundle exec rails server +bundle install --binstubs +bin/rails server ``` You will find Leap Web running on `localhost:3000`. Check out the Cert Distribution section below for setting up the cert and server config. @@ -50,7 +50,7 @@ We install most gems we depend upon through [bundler](http://gembundler.com). Fi Then install all the required gems: ``` - bundle install + bundle install --binstubs ``` ## Setup ## @@ -72,7 +72,7 @@ If you want to use that functionality please add your provider files the public/ ## Running ## ``` -bundle exec rails server +bin/rails server ``` You'll find Leap Web running on `localhost:3000` -- cgit v1.2.3 From 26bce716526bfc6a59ffbc372d34215ce2242bfe Mon Sep 17 00:00:00 2001 From: jessib Date: Thu, 28 Feb 2013 10:36:24 -0800 Subject: Have specific error messages for usernames with incorrect formats. Signed-off-by: jessib --- users/app/models/user.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/users/app/models/user.rb b/users/app/models/user.rb index b6e2bad..c9b367f 100644 --- a/users/app/models/user.rb +++ b/users/app/models/user.rb @@ -18,9 +18,19 @@ class User < CouchRest::Model::Base :uniqueness => true, :if => :serverside? + # Have multiple regular expression validations so we can get specific error messages: validates :login, - :format => { :with => /\A[a-z][a-z\d_\.-]*[a-z\d]\z/, - :message => "Only lowercase letters, digits, . - and _ allowed. Login must have at least 2 characters, and begin with a letter, and end with a letter or digit" } + :format => { :with => /\A.{2,}\z/, + :message => "Login 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"} + validates :login, + :format => { :with => /\A.*[a-z\d]\z/, + :message => "Login must end with a letter or digit"} validate :login_is_unique_alias -- cgit v1.2.3 From a3360da90e9c9b125c1e68861c049110370171ff Mon Sep 17 00:00:00 2001 From: Azul Date: Mon, 4 Mar 2013 17:50:06 +0100 Subject: make api test script work with bitmask and print log --- users/test/integration/api/python/flow_with_srp.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/users/test/integration/api/python/flow_with_srp.py b/users/test/integration/api/python/flow_with_srp.py index df83dfb..7b741d6 100755 --- a/users/test/integration/api/python/flow_with_srp.py +++ b/users/test/integration/api/python/flow_with_srp.py @@ -12,11 +12,11 @@ import binascii safe_unhexlify = lambda x: binascii.unhexlify(x) if (len(x) % 2 == 0) else binascii.unhexlify('0'+x) # let's have some random name -def id_generator(size=6, chars=string.ascii_uppercase + string.digits): +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 = 'http://api.lvh.me:3000/1' +server = 'https://api.bitmask.net:4430/1' login = id_generator() password = id_generator() + id_generator() @@ -25,9 +25,9 @@ password = id_generator() + id_generator() # log the server communication def print_and_parse(response): - # print response.request.method + ': ' + response.url - # print " " + json.dumps(response.request.data) - # print " -> " + response.text + print response.request.method + ': ' + response.url + print " " + json.dumps(response.request.data) + print " -> " + response.text return json.loads(response.text) def signup(session): @@ -39,7 +39,7 @@ def signup(session): 'user[password_verifier]': binascii.hexlify(vkey), 'user[password_salt]': binascii.hexlify(salt) } - return session.post(server + '/users.json', data = user_params) + return session.post(server + '/users.json', data = user_params, verify = False) usr = srp.User( login, password, srp.SHA256, srp.NG_1024 ) @@ -50,12 +50,12 @@ def authenticate(session, login): 'login': uname, 'A': binascii.hexlify(A) } - init = print_and_parse(session.post(server + '/sessions', data = params)) + 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, + return session.put(server + '/sessions/' + login, verify = False, data = {'client_auth': binascii.hexlify(M)}) session = requests.session() -- cgit v1.2.3 From 87c306ea212c01ecc8f98009def5971fc4d5af11 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 5 Mar 2013 13:26:56 +0100 Subject: minor: fixed logout link --- users/app/views/sessions/_nav.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/app/views/sessions/_nav.html.haml b/users/app/views/sessions/_nav.html.haml index 5306d0e..ac85bb5 100644 --- a/users/app/views/sessions/_nav.html.haml +++ b/users/app/views/sessions/_nav.html.haml @@ -5,7 +5,7 @@ %li = link_to current_user.login, edit_user_path(current_user) %li - = link_to t(:logout), logout_path + = link_to t(:logout), logout_path, :method => :delete - else %li = link_to t(:login), login_path -- cgit v1.2.3